1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/omnibox/browser/autocomplete_classifier.h"
#include <utility>
#include "base/auto_reset.h"
#include "base/feature_list.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/history_embeddings/history_embeddings_features.h"
#include "components/omnibox/browser/autocomplete_controller.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_provider.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/common/omnibox_feature_configs.h"
#include "components/omnibox/common/omnibox_features.h"
#include "extensions/buildflags/buildflags.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
#include "url/gurl.h"
#if !BUILDFLAG(IS_IOS)
#include "components/history_clusters/core/config.h" // nogncheck
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/extension_features.h" // nogncheck
#endif
AutocompleteClassifier::AutocompleteClassifier(
std::unique_ptr<AutocompleteController> controller,
std::unique_ptr<AutocompleteSchemeClassifier> scheme_classifier)
: controller_(std::move(controller)),
scheme_classifier_(std::move(scheme_classifier)),
inside_classify_(false) {}
AutocompleteClassifier::~AutocompleteClassifier() {
// We should only reach here after Shutdown() has been called.
DCHECK(!controller_);
}
void AutocompleteClassifier::Shutdown() {
controller_.reset();
}
// static
int AutocompleteClassifier::DefaultOmniboxProviders(bool is_low_memory_device) {
return
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
// Custom search engines cannot be used on mobile.
AutocompleteProvider::TYPE_KEYWORD | AutocompleteProvider::TYPE_OPEN_TAB |
AutocompleteProvider::TYPE_FEATURED_SEARCH |
// Most visited sites for desktop.
(omnibox_feature_configs::OmniboxUrlSuggestionsOnFocus::Get().enabled
? AutocompleteProvider::TYPE_MOST_VISITED_SITES
: 0) |
(omnibox_feature_configs::OmniboxUrlSuggestionsOnFocus::Get()
.show_recently_closed_tabs
? AutocompleteProvider::TYPE_RECENTLY_CLOSED_TABS
: 0) |
(omnibox_feature_configs::ContextualSearch::Get().show_open_lens_action ||
omnibox_feature_configs::Toolbelt::Get().enabled
? AutocompleteProvider::TYPE_CONTEXTUAL_SEARCH
: 0) |
#else
AutocompleteProvider::TYPE_CLIPBOARD |
AutocompleteProvider::TYPE_MOST_VISITED_SITES |
AutocompleteProvider::TYPE_VERBATIM_MATCH |
#endif
#if BUILDFLAG(IS_ANDROID)
AutocompleteProvider::TYPE_VOICE_SUGGEST |
// Only enabled for hub search.
AutocompleteProvider::TYPE_OPEN_TAB |
// Only enabled for hub search.
(base::FeatureList::IsEnabled(omnibox::kAndroidHubSearchTabGroups)
? AutocompleteProvider::TYPE_TAB_GROUP
: 0) |
#endif
#if !BUILDFLAG(IS_IOS)
(history_clusters::GetConfig().is_journeys_enabled_no_locale_check &&
history_clusters::GetConfig().omnibox_history_cluster_provider
? AutocompleteProvider::TYPE_HISTORY_CLUSTER_PROVIDER
: 0) |
#endif
AutocompleteProvider::TYPE_ZERO_SUGGEST |
AutocompleteProvider::TYPE_ZERO_SUGGEST_LOCAL_HISTORY |
(base::FeatureList::IsEnabled(omnibox::kDocumentProvider)
? AutocompleteProvider::TYPE_DOCUMENT
: 0) |
(OmniboxFieldTrial::IsOnDeviceHeadSuggestEnabledForAnyMode()
? AutocompleteProvider::TYPE_ON_DEVICE_HEAD
: 0) |
AutocompleteProvider::TYPE_BOOKMARK | AutocompleteProvider::TYPE_BUILTIN |
AutocompleteProvider::TYPE_HISTORY_QUICK |
AutocompleteProvider::TYPE_HISTORY_URL |
AutocompleteProvider::TYPE_SEARCH | AutocompleteProvider::TYPE_SHORTCUTS |
AutocompleteProvider::TYPE_HISTORY_FUZZY |
AutocompleteProvider::TYPE_CALCULATOR |
AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR |
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
(history_embeddings::GetFeatureParameters().omnibox_scoped ||
history_embeddings::GetFeatureParameters().omnibox_unscoped
? AutocompleteProvider::TYPE_HISTORY_EMBEDDINGS
: 0) |
#endif
#if BUILDFLAG(ENABLE_EXTENSIONS)
// `UnscopedExtensionProvider` should only be included when extensions are
// enabled and the `ExperimentalOmniboxLabs` feature is enabled.
(base::FeatureList::IsEnabled(
extensions_features::kExperimentalOmniboxLabs)
? AutocompleteProvider::TYPE_UNSCOPED_EXTENSION
: 0)
#else
0
#endif
;
}
void AutocompleteClassifier::Classify(
const std::u16string& text,
bool prefer_keyword,
bool allow_exact_keyword_match,
metrics::OmniboxEventProto::PageClassification page_classification,
AutocompleteMatch* match,
GURL* alternate_nav_url) {
TRACE_EVENT1("omnibox", "AutocompleteClassifier::Classify", "text",
base::UTF16ToUTF8(text));
DCHECK(!inside_classify_);
base::AutoReset<bool> reset(&inside_classify_, true);
AutocompleteInput input(text, page_classification, *scheme_classifier_);
input.set_prevent_inline_autocomplete(true);
// If the user in keyword mode (which is often the case when |prefer_keyword|
// is true), ideally we'd set |input|'s keyword_mode_entry_method field.
// However, in the context of this code, we don't know how the keyword mode
// was entered. Moreover, we cannot add that as a parameter to Classify()
// because many callers do not know how keyword mode was entered. Luckily,
// Classify()'s purpose is to determine the default match, and at this time
// |keyword_mode_entry_method| only ends up affecting the ranking of
// lower-down suggestions.
input.set_prefer_keyword(prefer_keyword);
input.set_allow_exact_keyword_match(allow_exact_keyword_match);
input.set_omit_asynchronous_matches(true);
controller_->Start(input);
DCHECK(controller_->done());
auto* default_match = controller_->result().default_match();
if (!default_match) {
if (alternate_nav_url)
*alternate_nav_url = GURL();
return;
}
*match = *default_match;
if (alternate_nav_url) {
*alternate_nav_url = AutocompleteResult::ComputeAlternateNavUrl(
input, *match, controller_->autocomplete_provider_client());
}
}
|