1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/omnibox/browser/autocomplete_classifier.h"
6
7 #include <utility>
8
9 #include "base/auto_reset.h"
10 #include "base/feature_list.h"
11 #include "base/ios/ios_util.h"
12 #include "build/build_config.h"
13 #include "components/omnibox/browser/autocomplete_controller.h"
14 #include "components/omnibox/browser/autocomplete_input.h"
15 #include "components/omnibox/browser/autocomplete_match.h"
16 #include "components/omnibox/browser/autocomplete_provider.h"
17 #include "components/omnibox/browser/document_provider.h"
18 #include "components/omnibox/browser/omnibox_field_trial.h"
19 #include "components/omnibox/common/omnibox_features.h"
20 #include "components/query_tiles/switches.h"
21 #include "third_party/metrics_proto/omnibox_event.pb.h"
22 #include "url/gurl.h"
23
AutocompleteClassifier(std::unique_ptr<AutocompleteController> controller,std::unique_ptr<AutocompleteSchemeClassifier> scheme_classifier)24 AutocompleteClassifier::AutocompleteClassifier(
25 std::unique_ptr<AutocompleteController> controller,
26 std::unique_ptr<AutocompleteSchemeClassifier> scheme_classifier)
27 : controller_(std::move(controller)),
28 scheme_classifier_(std::move(scheme_classifier)),
29 inside_classify_(false) {}
30
~AutocompleteClassifier()31 AutocompleteClassifier::~AutocompleteClassifier() {
32 // We should only reach here after Shutdown() has been called.
33 DCHECK(!controller_);
34 }
35
Shutdown()36 void AutocompleteClassifier::Shutdown() {
37 controller_.reset();
38 }
39
40 // static
DefaultOmniboxProviders()41 int AutocompleteClassifier::DefaultOmniboxProviders() {
42 return
43 #if !defined(OS_ANDROID) && !defined(OS_IOS)
44 // Custom search engines cannot be used on mobile.
45 AutocompleteProvider::TYPE_KEYWORD |
46 #else
47 AutocompleteProvider::TYPE_CLIPBOARD |
48 AutocompleteProvider::TYPE_MOST_VISITED_SITES |
49 AutocompleteProvider::TYPE_VERBATIM_MATCH |
50 #endif
51 AutocompleteProvider::TYPE_ZERO_SUGGEST |
52 AutocompleteProvider::TYPE_ZERO_SUGGEST_LOCAL_HISTORY |
53 (base::FeatureList::IsEnabled(omnibox::kDocumentProvider)
54 ? AutocompleteProvider::TYPE_DOCUMENT
55 : 0) |
56 (OmniboxFieldTrial::IsOnDeviceHeadSuggestEnabledForAnyMode()
57 ? AutocompleteProvider::TYPE_ON_DEVICE_HEAD
58 : 0) |
59 AutocompleteProvider::TYPE_BOOKMARK | AutocompleteProvider::TYPE_BUILTIN |
60 AutocompleteProvider::TYPE_HISTORY_QUICK |
61 AutocompleteProvider::TYPE_HISTORY_URL |
62 AutocompleteProvider::TYPE_SEARCH | AutocompleteProvider::TYPE_SHORTCUTS |
63 (query_tiles::features::IsEnabledQueryTilesInOmnibox()
64 ? AutocompleteProvider::TYPE_QUERY_TILE
65 : 0);
66 }
67
Classify(const base::string16 & text,bool prefer_keyword,bool allow_exact_keyword_match,metrics::OmniboxEventProto::PageClassification page_classification,AutocompleteMatch * match,GURL * alternate_nav_url)68 void AutocompleteClassifier::Classify(
69 const base::string16& text,
70 bool prefer_keyword,
71 bool allow_exact_keyword_match,
72 metrics::OmniboxEventProto::PageClassification page_classification,
73 AutocompleteMatch* match,
74 GURL* alternate_nav_url) {
75 DCHECK(!inside_classify_);
76 base::AutoReset<bool> reset(&inside_classify_, true);
77 AutocompleteInput input(text, page_classification, *scheme_classifier_);
78 input.set_prevent_inline_autocomplete(true);
79 // If the user in keyword mode (which is often the case when |prefer_keyword|
80 // is true), ideally we'd set |input|'s keyword_mode_entry_method field.
81 // However, in the context of this code, we don't know how the keyword mode
82 // was entered. Moreover, we cannot add that as a parameter to Classify()
83 // because many callers do not know how keyword mode was entered. Luckily,
84 // Classify()'s purpose is to determine the default match, and at this time
85 // |keyword_mode_entry_method| only ends up affecting the ranking of
86 // lower-down suggestions.
87 input.set_prefer_keyword(prefer_keyword);
88 input.set_allow_exact_keyword_match(allow_exact_keyword_match);
89 input.set_want_asynchronous_matches(false);
90 controller_->Start(input);
91 DCHECK(controller_->done());
92
93 auto* default_match = controller_->result().default_match();
94 if (!default_match) {
95 if (alternate_nav_url)
96 *alternate_nav_url = GURL();
97 return;
98 }
99
100 *match = *default_match;
101 if (alternate_nav_url) {
102 *alternate_nav_url = AutocompleteResult::ComputeAlternateNavUrl(
103 input, *match, controller_->autocomplete_provider_client());
104 }
105 }
106