15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_controller_delegate.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/bookmark_provider.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/builtin_provider.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/autocomplete/chrome_autocomplete_provider_client.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_quick_provider.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_url_provider.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/shortcuts_provider.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/zero_suggest_provider.h" 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/omnibox/keyword_provider.h" 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/omnibox/omnibox_field_trial.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/omnibox/search_provider.h" 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url.h" 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "grit/components_strings.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS) 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/autocomplete/keyword_extensions_delegate_impl.h" 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converts the given match to a type (and possibly subtype) based on the AQS 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// specification. For more details, see 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// http://goto.google.com/binary-clients-logging. 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutocompleteMatchToAssistedQuery( 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const AutocompleteMatch::Type& match, 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const AutocompleteProvider* provider, 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t* type, 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t* subtype) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This type indicates a native chrome suggestion. 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *type = 69; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Default value, indicating no subtype. 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *subtype = base::string16::npos; 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If provider is TYPE_ZERO_SUGGEST, set the subtype accordingly. 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Type will be set in the switch statement below where we'll enter one of 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // SEARCH_SUGGEST or NAVSUGGEST. This subtype indicates context-aware zero 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // suggest. 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (provider && 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (provider->type() == AutocompleteProvider::TYPE_ZERO_SUGGEST) && 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (match != AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED)) { 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK((match == AutocompleteMatchType::SEARCH_SUGGEST) || 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (match == AutocompleteMatchType::NAVSUGGEST)); 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *subtype = 66; 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (match) { 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::SEARCH_SUGGEST: { 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Do not set subtype here; subtype may have been set above. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *type = 0; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AutocompleteMatchType::SEARCH_SUGGEST_ENTITY: { 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *subtype = 46; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AutocompleteMatchType::SEARCH_SUGGEST_INFINITE: { 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *subtype = 33; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED: { 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *subtype = 39; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case AutocompleteMatchType::SEARCH_SUGGEST_PROFILE: { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *subtype = 44; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case AutocompleteMatchType::SEARCH_SUGGEST_ANSWER: { 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *subtype = 70; 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::NAVSUGGEST: { 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Do not set subtype here; subtype may have been set above. 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *type = 5; 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED: { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 57; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::URL_WHAT_YOU_TYPED: { 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 58; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::SEARCH_HISTORY: { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 59; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::HISTORY_URL: { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 60; 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::HISTORY_TITLE: { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 61; 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::HISTORY_BODY: { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 62; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::HISTORY_KEYWORD: { 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 63; 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case AutocompleteMatchType::BOOKMARK_TITLE: { 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 65; 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case AutocompleteMatchType::NAVSUGGEST_PERSONALIZED: { 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *subtype = 39; 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: { 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This value indicates a native chrome suggestion with no named subtype 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // (yet). 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *subtype = 64; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Appends available autocompletion of the given type, subtype, and number to 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the existing available autocompletions string, encoding according to the 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// spec. 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppendAvailableAutocompletion(size_t type, 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t subtype, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* autocompletions) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!autocompletions->empty()) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autocompletions->append("j"); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringAppendF(autocompletions, "%" PRIuS, type); 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Subtype is optional - base::string16::npos indicates no subtype. 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (subtype != base::string16::npos) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::StringAppendF(autocompletions, "i%" PRIuS, subtype); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count > 1) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(autocompletions, "l%d", count); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Returns whether the autocompletion is trivial enough that we consider it 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// an autocompletion for which the omnibox autocompletion code did not add 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// any value. 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool IsTrivialAutocompletion(const AutocompleteMatch& match) { 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return match.type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) match.type == AutocompleteMatchType::URL_WHAT_YOU_TYPED || 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) match.type == AutocompleteMatchType::SEARCH_OTHER_ENGINE; 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Whether this autocomplete match type supports custom descriptions. 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AutocompleteMatchHasCustomDescription(const AutocompleteMatch& match) { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY || 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) match.type == AutocompleteMatchType::SEARCH_SUGGEST_PROFILE; 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteController::AutocompleteController( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TemplateURLService* template_url_service, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteControllerDelegate* delegate, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int provider_types) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate), 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) history_url_provider_(NULL), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyword_provider_(NULL), 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) search_provider_(NULL), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zero_suggest_provider_(NULL), 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stop_timer_duration_(OmniboxFieldTrial::StopTimerFieldTrialDuration()), 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_(true), 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_start_(false), 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch template_url_service_(template_url_service) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) provider_types &= ~OmniboxFieldTrial::GetDisabledProviderTypes(); 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_BOOKMARK) 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch providers_.push_back(new BookmarkProvider(profile)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_BUILTIN) 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch providers_.push_back(new BuiltinProvider()); 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_HISTORY_QUICK) 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch providers_.push_back(new HistoryQuickProvider(profile)); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) { 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) history_url_provider_ = new HistoryURLProvider(this, profile); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) providers_.push_back(history_url_provider_); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // "Tab to search" can be used on all platforms other than Android. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_KEYWORD) { 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) keyword_provider_ = new KeywordProvider(this, template_url_service); 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS) 2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) keyword_provider_->set_extensions_delegate( 2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<KeywordExtensionsDelegate>( 2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) new KeywordExtensionsDelegateImpl(profile, keyword_provider_))); 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) providers_.push_back(keyword_provider_); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_SEARCH) { 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci search_provider_ = new SearchProvider( 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this, template_url_service, scoped_ptr<AutocompleteProviderClient>( 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new ChromeAutocompleteProviderClient(profile))); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) providers_.push_back(search_provider_); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_SHORTCUTS) 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch providers_.push_back(new ShortcutsProvider(profile)); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (provider_types & AutocompleteProvider::TYPE_ZERO_SUGGEST) { 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) zero_suggest_provider_ = ZeroSuggestProvider::Create( 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, template_url_service, profile); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (zero_suggest_provider_) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) providers_.push_back(zero_suggest_provider_); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteController::~AutocompleteController() { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The providers may have tasks outstanding that hold refs to them. We need 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to ensure they won't call us back if they outlive us. (Practically, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // calling Stop() should also cancel those tasks and make it so that we hold 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the only refs.) We also don't want to bother notifying anyone of our 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result changes here, because the notification observer is in the midst of 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shutdown too, so we don't ask Stop() to clear |result_| (and notify). 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_.Reset(); // Not really necessary. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(false); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteController::Start(const AutocompleteInput& input) { 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16 old_input_text(input_.text()); 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const bool old_want_asynchronous_matches = input_.want_asynchronous_matches(); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input_ = input; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See if we can avoid rerunning autocomplete when the query hasn't changed 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // much. When the user presses or releases the ctrl key, the desired_tld 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changes, and when the user finishes an IME composition, inline autocomplete 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // may no longer be prevented. In both these cases the text itself hasn't 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changed since the last query, and some providers can do much less work (and 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get matches back more quickly). Taking advantage of this reduces flicker. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: This comes after constructing |input_| above since that construction 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can change the text string (e.g. by stripping off a leading '?'). 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool minimal_changes = (input_.text() == old_input_text) && 2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (input_.want_asynchronous_matches() == old_want_asynchronous_matches); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expire_timer_.Stop(); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stop_timer_.Stop(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the new query. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_start_ = true; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks start_time = base::TimeTicks::Now(); 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::iterator i(providers_.begin()); i != providers_.end(); ++i) { 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(mpearson): Remove timing code once bugs 178705 / 237703 / 168933 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // are resolved. 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::TimeTicks provider_start_time = base::TimeTicks::Now(); 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Call Start() on ZeroSuggestProvider with an INVALID AutocompleteInput 267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // to clear out zero-suggest |matches_|. 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (i->get() == zero_suggest_provider_) 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch (*i)->Start(AutocompleteInput(), minimal_changes); 270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else 271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch (*i)->Start(input_, minimal_changes); 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!input.want_asynchronous_matches()) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((*i)->done()); 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::TimeTicks provider_end_time = base::TimeTicks::Now(); 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string name = std::string("Omnibox.ProviderTime.") + (*i)->GetName(); 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::HistogramBase* counter = base::Histogram::FactoryGet( 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) name, 1, 5000, 20, base::Histogram::kUmaTargetedHistogramFlag); 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) counter->Add(static_cast<int>( 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (provider_end_time - provider_start_time).InMilliseconds())); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (input.want_asynchronous_matches() && (input.text().length() < 6)) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks end_time = base::TimeTicks::Now(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name = "Omnibox.QueryTime." + base::IntToString( 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) input.text().length()); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HistogramBase* counter = base::Histogram::FactoryGet( 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter->Add(static_cast<int>((end_time - start_time).InMilliseconds())); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_start_ = false; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIfDone(); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The second true forces saying the default match has changed. 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This triggers the edit model to update things such as the inline 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // autocomplete state. In particular, if the user has typed a key 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // since the last notification, and we're now re-running 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // autocomplete, then we need to update the inline autocompletion 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // even if the current match is for the same URL as the last run's 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // default match. Likewise, the controller doesn't know what's 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // happened in the edit since the last time it ran autocomplete. 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The user might have selected all the text and hit delete, then 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // typed a new character. The selection and delete won't send any 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // signals to the controller so it doesn't realize that anything was 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cleared or changed. Even if the default match hasn't changed, we 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // need the edit model to update the display. 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateResult(false, true); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!done_) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartExpireTimer(); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartStopTimer(); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::Stop(bool clear_result) { 314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::const_iterator i(providers_.begin()); i != providers_.end(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->Stop(clear_result); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expire_timer_.Stop(); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stop_timer_.Stop(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = true; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (clear_result && !result_.empty()) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_.Reset(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: We pass in false since we're trying to only clear the popup, not 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // touch the edit... this is all a mess and should be cleaned up :( 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyChanged(false); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 330effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AutocompleteController::StartZeroSuggest(const AutocompleteInput& input) { 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (zero_suggest_provider_ == NULL) 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(!in_start_); // We should not be already running a query. 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Call Start() on all prefix-based providers with an INVALID 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // AutocompleteInput to clear out cached |matches_|, which ensures that 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // they aren't used with zero suggest. 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::iterator i(providers_.begin()); i != providers_.end(); ++i) { 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (i->get() == zero_suggest_provider_) 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (*i)->Start(input, false); 342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) else 343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (*i)->Start(AutocompleteInput(), false); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!zero_suggest_provider_->matches().empty()) 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) UpdateResult(false, false); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::DeleteMatch(const AutocompleteMatch& match) { 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(match.SupportsDeletion()); 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Delete duplicate matches attached to the main match first. 354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (ACMatches::const_iterator it(match.duplicate_matches.begin()); 355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it != match.duplicate_matches.end(); ++it) { 356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (it->deletable) 357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it->provider->DeleteMatch(*it); 358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (match.deletable) 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) match.provider->DeleteMatch(match); 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProviderUpdate(true); 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If we're not done, we might attempt to redisplay the deleted match. Make 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // sure we aren't displaying it by removing any old entries. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExpireCopiedEntries(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::ExpireCopiedEntries() { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The first true makes UpdateResult() clear out the results and 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // regenerate them, thus ensuring that no results from the previous 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // result set remain. 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateResult(true, false); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::OnProviderUpdate(bool updated_matches) { 37823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) CheckIfDone(); 37923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Multiple providers may provide synchronous results, so we only update the 38023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // results if we're not in Start(). 38123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!in_start_ && (updated_matches || done_)) 38223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) UpdateResult(false, false); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::AddProvidersInfo( 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProvidersInfo* provider_info) const { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider_info->clear(); 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::const_iterator i(providers_.begin()); i != providers_.end(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add per-provider info, if any. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->AddProviderInfo(provider_info); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is also a good place to put code to add info that you want to 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add for every provider. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteController::ResetSession() { 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::const_iterator i(providers_.begin()); i != providers_.end(); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++i) 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (*i)->ResetSession(); 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AutocompleteController::UpdateMatchDestinationURLWithQueryFormulationTime( 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta query_formulation_time, 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AutocompleteMatch* match) const { 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!match->search_terms_args.get() || 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) match->search_terms_args->assisted_query_stats.empty()) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Append the query formulation time (time from when the user first typed a 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // character into the omnibox to when the user selected a query) and whether 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // a field trial has triggered to the AQS parameter. 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TemplateURLRef::SearchTermsArgs search_terms_args(*match->search_terms_args); 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) search_terms_args.assisted_query_stats += base::StringPrintf( 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ".%" PRId64 "j%dj%d", 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) query_formulation_time.InMilliseconds(), 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (search_provider_ && 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) search_provider_->field_trial_triggered_in_session()) || 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (zero_suggest_provider_ && 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) zero_suggest_provider_->field_trial_triggered_in_session()), 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) input_.current_page_classification()); 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateMatchDestinationURL(search_terms_args, match); 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AutocompleteController::UpdateMatchDestinationURL( 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const TemplateURLRef::SearchTermsArgs& search_terms_args, 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AutocompleteMatch* match) const { 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TemplateURL* template_url = match->GetTemplateURL( 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) template_url_service_, false); 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!template_url) 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( 435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch search_terms_args, template_url_service_->search_terms_data())); 4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteController::UpdateResult( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool regenerate_result, 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool force_notify_default_match_changed) { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool last_default_was_valid = result_.default_match() != result_.end(); 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The following three variables are only set and used if 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |last_default_was_valid|. 444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 last_default_fill_into_edit, last_default_keyword, 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) last_default_associated_keyword; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_default_was_valid) { 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_default_fill_into_edit = result_.default_match()->fill_into_edit; 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) last_default_keyword = result_.default_match()->keyword; 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (result_.default_match()->associated_keyword != NULL) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_default_associated_keyword = 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result_.default_match()->associated_keyword->keyword; 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (regenerate_result) 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result_.Reset(); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteResult last_result; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_result.Swap(&result_); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::const_iterator i(providers_.begin()); 46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) i != providers_.end(); ++i) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_.AppendMatches((*i)->matches()); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort the matches and trim to a small number of "best" matches. 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result_.SortAndCull(input_, template_url_service_); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to validate before invoking CopyOldMatches as the old matches are not 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // valid against the current input. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_.Validate(); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!done_) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This conditional needs to match the conditional in Start that invokes 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // StartExpireTimer. 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result_.CopyOldMatches(input_, last_result, template_url_service_); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateKeywordDescriptions(&result_); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateAssociatedKeywords(&result_); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateAssistedQueryStats(&result_); 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (search_provider_) 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) search_provider_->RegisterDisplayedAnswers(result_); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool default_is_valid = result_.default_match() != result_.end(); 486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 default_associated_keyword; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (default_is_valid && 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (result_.default_match()->associated_keyword != NULL)) { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_associated_keyword = 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result_.default_match()->associated_keyword->keyword; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We've gotten async results. Send notification that the default match 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // updated if fill_into_edit, associated_keyword, or keyword differ. (The 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // second can change if we've just started Chrome and the keyword database 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // finishes loading while processing this request. The third can change 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // if we swapped from interpreting the input as a search--which gets 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // labeled with the default search provider's keyword--to a URL.) 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We don't check the URL as that may change for the default match 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // even though the fill into edit hasn't changed (see SearchProvider 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // for one case of this). 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool notify_default_match = 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (last_default_was_valid != default_is_valid) || 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (last_default_was_valid && 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ((result_.default_match()->fill_into_edit != 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_default_fill_into_edit) || 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (default_associated_keyword != last_default_associated_keyword) || 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (result_.default_match()->keyword != last_default_keyword))); 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (notify_default_match) 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_time_default_match_changed_ = base::TimeTicks::Now(); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyChanged(force_notify_default_match_changed || notify_default_match); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::UpdateAssociatedKeywords( 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteResult* result) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!keyword_provider_) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Determine if the user's input is an exact keyword match. 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::string16 exact_keyword = keyword_provider_->GetKeywordForText( 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TemplateURLService::CleanUserInputKeyword(input_.text())); 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::set<base::string16> keywords; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ACMatches::iterator match(result->begin()); match != result->end(); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++match) { 526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 keyword( 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch match->GetSubstitutingExplicitlyInvokedKeyword(template_url_service_)); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!keyword.empty()) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keywords.insert(keyword); 530eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch continue; 531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // When the user has typed an exact keyword, we want tab-to-search on the 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // default match to select that keyword, even if the match 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // inline-autocompletes to a different keyword. (This prevents inline 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // autocompletions from blocking a user's attempts to use an explicitly-set 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // keyword of their own creation.) So use |exact_keyword| if it's 5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // available. 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!exact_keyword.empty() && !keywords.count(exact_keyword)) { 5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) keywords.insert(exact_keyword); 5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) match->associated_keyword.reset(new AutocompleteMatch( 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) keyword_provider_->CreateVerbatimMatch(exact_keyword, 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exact_keyword, input_))); 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Otherwise, set a match's associated keyword based on the match's 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // fill_into_edit, which should take inline autocompletions into account. 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) keyword = keyword_provider_->GetKeywordForText(match->fill_into_edit); 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 551eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Only add the keyword if the match does not have a duplicate keyword with 552eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // a more relevant match. 553eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!keyword.empty() && !keywords.count(keyword)) { 554eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch keywords.insert(keyword); 5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) match->associated_keyword.reset(new AutocompleteMatch( 5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) keyword_provider_->CreateVerbatimMatch(match->fill_into_edit, 5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) keyword, input_))); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch match->associated_keyword.reset(); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void AutocompleteController::UpdateKeywordDescriptions( 5653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AutocompleteResult* result) { 566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 last_keyword; 5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (AutocompleteResult::iterator i(result->begin()); i != result->end(); 5683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++i) { 569effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (AutocompleteMatch::IsSearchType(i->type)) { 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (AutocompleteMatchHasCustomDescription(*i)) 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 5723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i->description.clear(); 5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i->description_class.clear(); 5743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!i->keyword.empty()); 5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (i->keyword != last_keyword) { 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const TemplateURL* template_url = 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch i->GetTemplateURL(template_url_service_, false); 5783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (template_url) { 5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // For extension keywords, just make the description the extension 5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // name -- don't assume that the normal search keyword description is 5813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // applicable. 5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i->description = template_url->AdjustedShortNameForLocaleDirection(); 5831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (template_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION) { 5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i->description = l10n_util::GetStringFUTF16( 5853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION, i->description); 5863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) i->description_class.push_back( 5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ACMatchClassification(0, ACMatchClassification::DIM)); 5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) last_keyword = i->keyword; 5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 5933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) last_keyword.clear(); 5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::UpdateAssistedQueryStats( 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteResult* result) { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->empty()) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build the impressions string (the AQS part after "."). 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string autocompletions; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 606a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t last_type = base::string16::npos; 607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t last_subtype = base::string16::npos; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ACMatches::iterator match(result->begin()); match != result->end(); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++match) { 610a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t type = base::string16::npos; 611a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) size_t subtype = base::string16::npos; 612010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) AutocompleteMatchToAssistedQuery( 613010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) match->type, match->provider, &type, &subtype); 614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (last_type != base::string16::npos && 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (type != last_type || subtype != last_subtype)) { 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AppendAvailableAutocompletion( 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) last_type, last_subtype, count, &autocompletions); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = 1; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count++; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_type = type; 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) last_subtype = subtype; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AppendAvailableAutocompletion( 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) last_type, last_subtype, count, &autocompletions); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Go over all matches and set AQS if the match supports it. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t index = 0; index < result->size(); ++index) { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteMatch* match = result->match_at(index); 630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const TemplateURL* template_url = 631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch match->GetTemplateURL(template_url_service_, false); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!template_url || !match->search_terms_args.get()) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string selected_index; 6357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Prevent trivial suggestions from getting credit for being selected. 6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!IsTrivialAutocompletion(*match)) 6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) selected_index = base::StringPrintf("%" PRIuS, index); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match->search_terms_args->assisted_query_stats = 6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::StringPrintf("chrome.%s.%s", 6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) selected_index.c_str(), 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autocompletions.c_str()); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms( 643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *match->search_terms_args, template_url_service_->search_terms_data())); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::NotifyChanged(bool notify_default_match) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnResultChanged(notify_default_match); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (done_) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY, 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<AutocompleteController>(this), 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::CheckIfDone() { 659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (Providers::const_iterator i(providers_.begin()); i != providers_.end(); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i) { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(*i)->done()) { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = false; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = true; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::StartExpireTimer() { 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Amount of time (in ms) between when the user stops typing and 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // when we remove any copied entries. We do this from the time the 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // user stopped typing as some providers (such as SearchProvider) 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // wait for the user to stop typing before they initiate a query. 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int kExpireTimeMS = 500; 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_.HasCopiedMatches()) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expire_timer_.Start(FROM_HERE, 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kExpireTimeMS), 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &AutocompleteController::ExpireCopiedEntries); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutocompleteController::StartStopTimer() { 6837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch stop_timer_.Start(FROM_HERE, 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stop_timer_duration_, 6857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&AutocompleteController::Stop, 6867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Unretained(this), 6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch false)); 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 689