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