autocomplete_controller.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/command_line.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_controller_delegate.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/bookmark_provider.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/builtin_provider.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/extension_app_provider.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_quick_provider.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/history_url_provider.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/keyword_provider.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/search_provider.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/shortcuts_provider.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/zero_suggest_provider.h"
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/omnibox/omnibox_field_trial.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/search/search.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/search_engines/template_url.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/contact_provider_chromeos.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/contacts/contact_manager.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converts the given match to a type (and possibly subtype) based on the AQS
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// specification. For more details, see
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// http://goto.google.com/binary-clients-logging.
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutocompleteMatchToAssistedQuery(
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const AutocompleteMatch::Type& match, size_t* type, size_t* subtype) {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This type indicates a native chrome suggestion.
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *type = 69;
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Default value, indicating no subtype.
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  *subtype = base::string16::npos;
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (match) {
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::SEARCH_SUGGEST: {
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *type = 0;
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case AutocompleteMatchType::SEARCH_SUGGEST_ENTITY: {
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *subtype = 46;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case AutocompleteMatchType::SEARCH_SUGGEST_INFINITE: {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *subtype = 33;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case AutocompleteMatchType::SEARCH_SUGGEST_PERSONALIZED: {
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *subtype = 35;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case AutocompleteMatchType::SEARCH_SUGGEST_PROFILE: {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      *subtype = 44;
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::NAVSUGGEST: {
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *type = 5;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED: {
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 57;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::URL_WHAT_YOU_TYPED: {
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 58;
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::SEARCH_HISTORY: {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 59;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::HISTORY_URL: {
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 60;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::HISTORY_TITLE: {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 61;
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::HISTORY_BODY: {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 62;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::HISTORY_KEYWORD: {
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 63;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case AutocompleteMatchType::BOOKMARK_TITLE: {
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 65;
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default: {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // This value indicates a native chrome suggestion with no named subtype
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // (yet).
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *subtype = 64;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Appends available autocompletion of the given type, subtype, and number to
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the existing available autocompletions string, encoding according to the
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// spec.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AppendAvailableAutocompletion(size_t type,
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   size_t subtype,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int count,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   std::string* autocompletions) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!autocompletions->empty())
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    autocompletions->append("j");
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::StringAppendF(autocompletions, "%" PRIuS, type);
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Subtype is optional - base::string16::npos indicates no subtype.
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (subtype != base::string16::npos)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::StringAppendF(autocompletions, "i%" PRIuS, subtype);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (count > 1)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::StringAppendF(autocompletions, "l%d", count);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Returns whether the autocompletion is trivial enough that we consider it
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// an autocompletion for which the omnibox autocompletion code did not add
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// any value.
1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool IsTrivialAutocompletion(const AutocompleteMatch& match) {
1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return match.type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED ||
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      match.type == AutocompleteMatchType::URL_WHAT_YOU_TYPED ||
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      match.type == AutocompleteMatchType::SEARCH_OTHER_ENGINE;
1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Whether this autocomplete match type supports custom descriptions.
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AutocompleteMatchHasCustomDescription(const AutocompleteMatch& match) {
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return match.type == AutocompleteMatchType::SEARCH_SUGGEST_ENTITY ||
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      match.type == AutocompleteMatchType::SEARCH_SUGGEST_PROFILE;
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteController::AutocompleteController(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutocompleteControllerDelegate* delegate,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int provider_types)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(delegate),
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      history_url_provider_(NULL),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keyword_provider_(NULL),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      search_provider_(NULL),
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zero_suggest_provider_(NULL),
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stop_timer_duration_(OmniboxFieldTrial::StopTimerFieldTrialDuration()),
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      done_(true),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      in_start_(false),
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      in_zero_suggest_(false),
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(profile) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // AND with the disabled providers, if any.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  provider_types &= ~OmniboxFieldTrial::GetDisabledProviderTypes();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool use_hqp = !!(provider_types & AutocompleteProvider::TYPE_HISTORY_QUICK);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mrossetti): Permanently modify the HistoryURLProvider to not search
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // titles once HQP is turned on permanently.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_BUILTIN)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(new BuiltinProvider(this, profile));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_CONTACT)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(new ContactProvider(this, profile,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        contacts::ContactManager::GetInstance()->GetWeakPtr()));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_EXTENSION_APP)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(new ExtensionAppProvider(this, profile));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (use_hqp)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(new HistoryQuickProvider(this, profile));
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_HISTORY_URL) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    history_url_provider_ = new HistoryURLProvider(this, profile);
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    providers_.push_back(history_url_provider_);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Search provider/"tab to search" can be used on all platforms other than
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Android.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_KEYWORD) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyword_provider_ = new KeywordProvider(this, profile);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(keyword_provider_);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_SEARCH) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    search_provider_ = new SearchProvider(this, profile);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(search_provider_);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_SHORTCUTS)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(new ShortcutsProvider(this, profile));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create ZeroSuggest if it is enabled.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (provider_types & AutocompleteProvider::TYPE_ZERO_SUGGEST) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zero_suggest_provider_ = ZeroSuggestProvider::Create(this, profile);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (zero_suggest_provider_)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      providers_.push_back(zero_suggest_provider_);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((provider_types & AutocompleteProvider::TYPE_BOOKMARK) &&
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          switches::kDisableBookmarkAutocompleteProvider))
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    providers_.push_back(new BookmarkProvider(this, profile));
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->AddRef();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteController::~AutocompleteController() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The providers may have tasks outstanding that hold refs to them.  We need
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to ensure they won't call us back if they outlive us.  (Practically,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calling Stop() should also cancel those tasks and make it so that we hold
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the only refs.)  We also don't want to bother notifying anyone of our
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // result changes here, because the notification observer is in the midst of
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shutdown too, so we don't ask Stop() to clear |result_| (and notify).
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_.Reset();  // Not really necessary.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop(false);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::iterator i(providers_.begin()); i != providers_.end(); ++i)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->Release();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  providers_.clear();  // Not really necessary.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteController::Start(const AutocompleteInput& input) {
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16 old_input_text(input_.text());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AutocompleteInput::MatchesRequested old_matches_requested =
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      input_.matches_requested();
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  input_ = input;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See if we can avoid rerunning autocomplete when the query hasn't changed
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // much.  When the user presses or releases the ctrl key, the desired_tld
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changes, and when the user finishes an IME composition, inline autocomplete
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // may no longer be prevented.  In both these cases the text itself hasn't
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // changed since the last query, and some providers can do much less work (and
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get matches back more quickly).  Taking advantage of this reduces flicker.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: This comes after constructing |input_| above since that construction
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can change the text string (e.g. by stripping off a leading '?').
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool minimal_changes = (input_.text() == old_input_text) &&
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (input_.matches_requested() == old_matches_requested);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expire_timer_.Stop();
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stop_timer_.Stop();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the new query.
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_zero_suggest_ = false;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_start_ = true;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::Now();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::iterator i(providers_.begin()); i != providers_.end();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(mpearson): Remove timing code once bugs 178705 / 237703 / 168933
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // are resolved.
26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::TimeTicks provider_start_time = base::TimeTicks::Now();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->Start(input_, minimal_changes);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (input.matches_requested() != AutocompleteInput::ALL_MATCHES)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK((*i)->done());
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::TimeTicks provider_end_time = base::TimeTicks::Now();
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string name = std::string("Omnibox.ProviderTime.") + (*i)->GetName();
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::HistogramBase* counter = base::Histogram::FactoryGet(
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        name, 1, 5000, 20, base::Histogram::kUmaTargetedHistogramFlag);
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    counter->Add(static_cast<int>(
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        (provider_end_time - provider_start_time).InMilliseconds()));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input.matches_requested() == AutocompleteInput::ALL_MATCHES &&
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (input.text().length() < 6)) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeTicks end_time = base::TimeTicks::Now();
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string name = "Omnibox.QueryTime." + base::IntToString(
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        input.text().length());
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::HistogramBase* counter = base::Histogram::FactoryGet(
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name, 1, 1000, 50, base::Histogram::kUmaTargetedHistogramFlag);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    counter->Add(static_cast<int>((end_time - start_time).InMilliseconds()));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_start_ = false;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckIfDone();
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second true forces saying the default match has changed.
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This triggers the edit model to update things such as the inline
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // autocomplete state.  In particular, if the user has typed a key
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // since the last notification, and we're now re-running
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // autocomplete, then we need to update the inline autocompletion
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // even if the current match is for the same URL as the last run's
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // default match.  Likewise, the controller doesn't know what's
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // happened in the edit since the last time it ran autocomplete.
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The user might have selected all the text and hit delete, then
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // typed a new character.  The selection and delete won't send any
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // signals to the controller so it doesn't realize that anything was
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // cleared or changed.  Even if the default match hasn't changed, we
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // need the edit model to update the display.
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateResult(false, true);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!done_) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartExpireTimer();
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartStopTimer();
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::Stop(bool clear_result) {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->Stop(clear_result);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expire_timer_.Stop();
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stop_timer_.Stop();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done_ = true;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (clear_result && !result_.empty()) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_.Reset();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: We pass in false since we're trying to only clear the popup, not
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // touch the edit... this is all a mess and should be cleaned up :(
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyChanged(false);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid AutocompleteController::StartZeroSuggest(
326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const GURL& url,
327d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    AutocompleteInput::PageClassification page_classification,
328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& permanent_text) {
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (zero_suggest_provider_ != NULL) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!in_start_);  // We should not be already running a query.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    in_zero_suggest_ = true;
332d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    zero_suggest_provider_->StartZeroSuggest(
333d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        url, page_classification, permanent_text);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::StopZeroSuggest() {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (zero_suggest_provider_ != NULL) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!in_start_);  // We should not be already running a query.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zero_suggest_provider_->Stop(false);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::DeleteMatch(const AutocompleteMatch& match) {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(match.deletable);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  match.provider->DeleteMatch(match);  // This may synchronously call back to
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       // OnProviderUpdate().
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If DeleteMatch resulted in a callback to OnProviderUpdate and we're
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not done, we might attempt to redisplay the deleted match. Make sure
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we aren't displaying it by removing any old entries.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpireCopiedEntries();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::ExpireCopiedEntries() {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first true makes UpdateResult() clear out the results and
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // regenerate them, thus ensuring that no results from the previous
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // result set remain.
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateResult(true, false);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::OnProviderUpdate(bool updated_matches) {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (in_zero_suggest_) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We got ZeroSuggest results before Start(). Show only those results,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // because results from other providers are stale.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_.Reset();
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_.AppendMatches(zero_suggest_provider_->matches());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_.SortAndCull(input_, profile_);
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    UpdateAssistedQueryStats(&result_);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyChanged(true);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckIfDone();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Multiple providers may provide synchronous results, so we only update the
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // results if we're not in Start().
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!in_start_ && (updated_matches || done_))
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateResult(false, false);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::AddProvidersInfo(
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProvidersInfo* provider_info) const {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  provider_info->clear();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add per-provider info, if any.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*i)->AddProviderInfo(provider_info);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is also a good place to put code to add info that you want to
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // add for every provider.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteController::ResetSession() {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++i)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*i)->ResetSession();
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  in_zero_suggest_ = false;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AutocompleteController::UpdateMatchDestinationURL(
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::TimeDelta query_formulation_time,
401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    AutocompleteMatch* match) const {
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TemplateURL* template_url = match->GetTemplateURL(profile_, false);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!template_url || !match->search_terms_args.get() ||
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      match->search_terms_args->assisted_query_stats.empty())
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Append the query formulation time (time from when the user first typed a
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // character into the omnibox to when the user selected a query) and whether
409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // a field trial has triggered to the AQS parameter.
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TemplateURLRef::SearchTermsArgs search_terms_args(*match->search_terms_args);
411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  search_terms_args.assisted_query_stats += base::StringPrintf(
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ".%" PRId64 "j%dj%d",
413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      query_formulation_time.InMilliseconds(),
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (search_provider_ &&
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       search_provider_->field_trial_triggered_in_session()) ||
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      (zero_suggest_provider_ &&
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       zero_suggest_provider_->field_trial_triggered_in_session()),
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      input_.current_page_classification());
419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  match->destination_url =
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      GURL(template_url->url_ref().ReplaceSearchTerms(search_terms_args));
4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteController::UpdateResult(
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool regenerate_result,
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool force_notify_default_match_changed) {
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool last_default_was_valid = result_.default_match() != result_.end();
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The following three variables are only set and used if
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |last_default_was_valid|.
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 last_default_fill_into_edit, last_default_keyword,
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      last_default_associated_keyword;
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_default_was_valid) {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_default_fill_into_edit = result_.default_match()->fill_into_edit;
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_default_keyword = result_.default_match()->keyword;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (result_.default_match()->associated_keyword != NULL)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_default_associated_keyword =
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          result_.default_match()->associated_keyword->keyword;
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (regenerate_result)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result_.Reset();
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutocompleteResult last_result;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_result.Swap(&result_);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_.AppendMatches((*i)->matches());
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sort the matches and trim to a small number of "best" matches.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_.SortAndCull(input_, profile_);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to validate before invoking CopyOldMatches as the old matches are not
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // valid against the current input.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result_.Validate();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!done_) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This conditional needs to match the conditional in Start that invokes
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // StartExpireTimer.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_.CopyOldMatches(input_, last_result, profile_);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateKeywordDescriptions(&result_);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAssociatedKeywords(&result_);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAssistedQueryStats(&result_);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool default_is_valid = result_.default_match() != result_.end();
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 default_associated_keyword;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (default_is_valid &&
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (result_.default_match()->associated_keyword != NULL)) {
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default_associated_keyword =
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        result_.default_match()->associated_keyword->keyword;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We've gotten async results. Send notification that the default match
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // updated if fill_into_edit, associated_keyword, or keyword differ.  (The
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // second can change if we've just started Chrome and the keyword database
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // finishes loading while processing this request.  The third can change
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // if we swapped from interpreting the input as a search--which gets
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // labeled with the default search provider's keyword--to a URL.)
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We don't check the URL as that may change for the default match
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // even though the fill into edit hasn't changed (see SearchProvider
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // for one case of this).
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool notify_default_match =
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (last_default_was_valid != default_is_valid) ||
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (last_default_was_valid &&
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ((result_.default_match()->fill_into_edit !=
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          last_default_fill_into_edit) ||
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (default_associated_keyword != last_default_associated_keyword) ||
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (result_.default_match()->keyword != last_default_keyword)));
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (notify_default_match)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_time_default_match_changed_ = base::TimeTicks::Now();
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotifyChanged(force_notify_default_match_changed || notify_default_match);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::UpdateAssociatedKeywords(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutocompleteResult* result) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!keyword_provider_)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::set<base::string16> keywords;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACMatches::iterator match(result->begin()); match != result->end();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++match) {
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 keyword(
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        match->GetSubstitutingExplicitlyInvokedKeyword(profile_));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!keyword.empty()) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keywords.insert(keyword);
509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      continue;
510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Only add the keyword if the match does not have a duplicate keyword with
513eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // a more relevant match.
514eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    keyword = match->associated_keyword.get() ?
515eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        match->associated_keyword->keyword :
516eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        keyword_provider_->GetKeywordForText(match->fill_into_edit);
517eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (!keyword.empty() && !keywords.count(keyword)) {
518eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      keywords.insert(keyword);
519eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!match->associated_keyword.get())
521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        match->associated_keyword.reset(new AutocompleteMatch(
522c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch            keyword_provider_->CreateVerbatimMatch(match->fill_into_edit,
523c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                                   keyword, input_)));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
525eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      match->associated_keyword.reset();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void AutocompleteController::UpdateKeywordDescriptions(
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    AutocompleteResult* result) {
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 last_keyword;
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (AutocompleteResult::iterator i(result->begin()); i != result->end();
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       ++i) {
5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if ((i->provider->type() == AutocompleteProvider::TYPE_KEYWORD &&
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         !i->keyword.empty()) ||
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        (i->provider->type() == AutocompleteProvider::TYPE_SEARCH &&
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         AutocompleteMatch::IsSearchType(i->type))) {
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (AutocompleteMatchHasCustomDescription(*i))
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        continue;
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      i->description.clear();
5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      i->description_class.clear();
5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DCHECK(!i->keyword.empty());
5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (i->keyword != last_keyword) {
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        const TemplateURL* template_url = i->GetTemplateURL(profile_, false);
5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        if (template_url) {
5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          // For extension keywords, just make the description the extension
5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          // name -- don't assume that the normal search keyword description is
5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          // applicable.
5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          i->description = template_url->AdjustedShortNameForLocaleDirection();
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          if (template_url->GetType() != TemplateURL::OMNIBOX_API_EXTENSION) {
5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            i->description = l10n_util::GetStringFUTF16(
5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION, i->description);
5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          }
5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          i->description_class.push_back(
5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              ACMatchClassification(0, ACMatchClassification::DIM));
5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        }
5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        last_keyword = i->keyword;
5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
5603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      last_keyword.clear();
5623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::UpdateAssistedQueryStats(
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutocompleteResult* result) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result->empty())
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the impressions string (the AQS part after ".").
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string autocompletions;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count = 0;
574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t last_type = base::string16::npos;
575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t last_subtype = base::string16::npos;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACMatches::iterator match(result->begin()); match != result->end();
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++match) {
578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    size_t type = base::string16::npos;
579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    size_t subtype = base::string16::npos;
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AutocompleteMatchToAssistedQuery(match->type, &type, &subtype);
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (last_type != base::string16::npos &&
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (type != last_type || subtype != last_subtype)) {
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AppendAvailableAutocompletion(
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          last_type, last_subtype, count, &autocompletions);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count = 1;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count++;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_type = type;
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_subtype = subtype;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AppendAvailableAutocompletion(
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      last_type, last_subtype, count, &autocompletions);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go over all matches and set AQS if the match supports it.
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < result->size(); ++index) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutocompleteMatch* match = result->match_at(index);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TemplateURL* template_url = match->GetTemplateURL(profile_, false);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!template_url || !match->search_terms_args.get())
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string selected_index;
6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Prevent trivial suggestions from getting credit for being selected.
6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (!IsTrivialAutocompletion(*match))
6037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      selected_index = base::StringPrintf("%" PRIuS, index);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    match->search_terms_args->assisted_query_stats =
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::StringPrintf("chrome.%s.%s",
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                           selected_index.c_str(),
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           autocompletions.c_str());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    match->destination_url = GURL(template_url->url_ref().ReplaceSearchTerms(
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *match->search_terms_args));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::NotifyChanged(bool notify_default_match) {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnResultChanged(notify_default_match);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (done_) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::NotificationService::current()->Notify(
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<AutocompleteController>(this),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::NoDetails());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::CheckIfDone() {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ACProviders::const_iterator i(providers_.begin()); i != providers_.end();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(*i)->done()) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      done_ = false;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  done_ = true;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteController::StartExpireTimer() {
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Amount of time (in ms) between when the user stops typing and
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // when we remove any copied entries. We do this from the time the
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // user stopped typing as some providers (such as SearchProvider)
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // wait for the user to stop typing before they initiate a query.
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int kExpireTimeMS = 500;
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result_.HasCopiedMatches())
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expire_timer_.Start(FROM_HERE,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        base::TimeDelta::FromMilliseconds(kExpireTimeMS),
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        this, &AutocompleteController::ExpireCopiedEntries);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutocompleteController::StartStopTimer() {
6497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  stop_timer_.Start(FROM_HERE,
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    stop_timer_duration_,
6517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                    base::Bind(&AutocompleteController::Stop,
6527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               base::Unretained(this),
6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                               false));
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
655