keyword_extensions_delegate_impl.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/autocomplete/keyword_extensions_delegate_impl.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/extensions/api/omnibox/omnibox_api.h" 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/extensions/extension_util.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/browser/notification_details.h" 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/browser/notification_source.h" 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/browser/extension_system.h" 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace omnibox_api = extensions::api::omnibox; 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int KeywordExtensionsDelegateImpl::global_input_uid_ = 0; 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)KeywordExtensionsDelegateImpl::KeywordExtensionsDelegateImpl( 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) KeywordProvider* provider) 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : KeywordExtensionsDelegate(provider), 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_(provider) { 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(provider_); 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_input_id_ = 0; 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Extension suggestions always come from the original profile, since that's 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // where extensions run. We use the input ID to distinguish whether the 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // suggestions are meant for us. 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) registrar_.Add( 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY, 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::Source<Profile>(profile()->GetOriginalProfile())); 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) registrar_.Add( 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED, 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::Source<Profile>(profile()->GetOriginalProfile())); 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) registrar_.Add( 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED, 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) content::Source<Profile>(profile())); 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)KeywordExtensionsDelegateImpl::~KeywordExtensionsDelegateImpl() { 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void KeywordExtensionsDelegateImpl::IncrementInputId() { 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_input_id_ = ++global_input_uid_; 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool KeywordExtensionsDelegateImpl::IsEnabledExtension( 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) Profile* profile, 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& extension_id) { 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ExtensionService* extension_service = 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::ExtensionSystem::Get(profile)->extension_service(); 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const extensions::Extension* extension = 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_service->GetExtensionById(extension_id, false); 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return extension && 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (!profile->IsOffTheRecord() || 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !extensions::util::IsIncognitoEnabled(extension_id, profile)); 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool KeywordExtensionsDelegateImpl::Start( 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AutocompleteInput& input, 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool minimal_changes, 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const TemplateURL* template_url, 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::string16& remaining_input) { 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(template_url); 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (input.want_asynchronous_matches()) { 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string extension_id = template_url->GetExtensionId(); 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (extension_id != current_keyword_extension_id_) 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) MaybeEndExtensionKeywordMode(); 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (current_keyword_extension_id_.empty()) 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EnterExtensionKeywordMode(extension_id); 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::ApplyDefaultSuggestionForExtensionKeyword( 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) profile(), template_url, remaining_input, &matches()->front()); 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (minimal_changes) { 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // If the input hasn't significantly changed, we can just use the 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // suggestions from last time. We need to readjust the relevance to 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // ensure it is less than the main match's relevance. 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (size_t i = 0; i < extension_suggest_matches_.size(); ++i) { 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matches()->push_back(extension_suggest_matches_[i]); 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matches()->back().relevance = matches()->front().relevance - (i + 1); 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } else if (input.want_asynchronous_matches()) { 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_suggest_last_input_ = input; 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_suggest_matches_.clear(); 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We only have to wait for suggest results if there are actually 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // extensions listening for input changes. 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (extensions::ExtensionOmniboxEventRouter::OnInputChanged( 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) profile(), template_url->GetExtensionId(), 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::UTF16ToUTF8(remaining_input), current_input_id_)) 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) set_done(false); 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return input.want_asynchronous_matches(); 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void KeywordExtensionsDelegateImpl::EnterExtensionKeywordMode( 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& extension_id) { 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(current_keyword_extension_id_.empty()); 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_keyword_extension_id_ = extension_id; 10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::ExtensionOmniboxEventRouter::OnInputStarted( 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) profile(), current_keyword_extension_id_); 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void KeywordExtensionsDelegateImpl::MaybeEndExtensionKeywordMode() { 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!current_keyword_extension_id_.empty()) { 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::ExtensionOmniboxEventRouter::OnInputCancelled( 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) profile(), current_keyword_extension_id_); 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_keyword_extension_id_.clear(); 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void KeywordExtensionsDelegateImpl::Observe( 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int type, 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const content::NotificationSource& source, 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const content::NotificationDetails& details) { 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) TemplateURLService* model = provider_->GetTemplateURLService(); 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const AutocompleteInput& input = extension_suggest_last_input_; 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (type) { 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_OMNIBOX_INPUT_ENTERED: 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Input has been accepted, so we're done with this input session. Ensure 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // we don't send the OnInputCancelled event, or handle any more stray 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // suggestions_ready events. 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_keyword_extension_id_.clear(); 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) current_input_id_ = 0; 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED: { 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // It's possible to change the default suggestion while not in an editing 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // session. 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::string16 keyword, remaining_input; 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (matches()->empty() || current_keyword_extension_id_.empty() || 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !KeywordProvider::ExtractKeywordFromInput( 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input, &keyword, &remaining_input)) 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const TemplateURL* template_url( 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) model->GetTemplateURLForKeyword(keyword)); 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::ApplyDefaultSuggestionForExtensionKeyword( 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) profile(), template_url, remaining_input, &matches()->front()); 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OnProviderUpdate(true); 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_OMNIBOX_SUGGESTIONS_READY: { 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const omnibox_api::SendSuggestions::Params& suggestions = 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *content::Details< 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) omnibox_api::SendSuggestions::Params>(details).ptr(); 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (suggestions.request_id != current_input_id_) 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; // This is an old result. Just ignore. 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::string16 keyword, remaining_input; 15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool result = KeywordProvider::ExtractKeywordFromInput( 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input, &keyword, &remaining_input); 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(result); 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const TemplateURL* template_url = 16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) model->GetTemplateURLForKeyword(keyword); 16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // TODO(mpcomplete): consider clamping the number of suggestions to 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // AutocompleteProvider::kMaxMatches. 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (size_t i = 0; i < suggestions.suggest_results.size(); ++i) { 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const omnibox_api::SuggestResult& suggestion = 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) *suggestions.suggest_results[i]; 17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We want to order these suggestions in descending order, so start with 17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the relevance of the first result (added synchronously in Start()), 17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // and subtract 1 for each subsequent suggestion from the extension. 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We recompute the first match's relevance; we know that |complete| 17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // is true, because we wouldn't get results from the extension unless 17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the full keyword had been typed. 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int first_relevance = KeywordProvider::CalculateRelevance( 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input.type(), true, true, input.prefer_keyword(), 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) input.allow_exact_keyword_match()); 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Because these matches are async, we should never let them become the 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // default match, lest we introduce race conditions in the omnibox user 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // interaction. 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_suggest_matches_.push_back( 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_->CreateAutocompleteMatch( 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) template_url, input, keyword.length(), 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::UTF8ToUTF16(suggestion.content), false, 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) first_relevance - (i + 1))); 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AutocompleteMatch* match = &extension_suggest_matches_.back(); 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) match->contents.assign(base::UTF8ToUTF16(suggestion.description)); 19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) match->contents_class = 19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extensions::StyleTypesToACMatchClassifications(suggestion); 19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) set_done(true); 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) matches()->insert(matches()->end(), 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_suggest_matches_.begin(), 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension_suggest_matches_.end()); 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OnProviderUpdate(!extension_suggest_matches_.empty()); 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) default: 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NOTREACHED(); 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return; 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void KeywordExtensionsDelegateImpl::OnProviderUpdate(bool updated_matches) { 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) provider_->listener_->OnProviderUpdate(updated_matches); 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 211