|  | // Copyright 2014 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_MATCH_H_ | 
|  | #define COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_MATCH_H_ | 
|  |  | 
|  | #include <stddef.h> | 
|  |  | 
|  | #include <array> | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <optional> | 
|  | #include <ranges> | 
|  | #include <string> | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/memory/raw_ptr.h" | 
|  | #include "base/memory/scoped_refptr.h" | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "base/strings/utf_offset_string_conversions.h" | 
|  | #include "base/uuid.h" | 
|  | #include "build/build_config.h" | 
|  | #include "components/omnibox/browser/actions/omnibox_action_concepts.h" | 
|  | #include "components/omnibox/browser/autocomplete_input.h" | 
|  | #include "components/omnibox/browser/autocomplete_match_type.h" | 
|  | #include "components/omnibox/browser/buildflags.h" | 
|  | #include "components/omnibox/browser/suggestion_answer.h" | 
|  | #include "components/saved_tab_groups/public/types.h" | 
|  | #include "components/search_engines/template_url.h" | 
|  | #include "components/url_formatter/url_formatter.h" | 
|  | #include "third_party/metrics_proto/omnibox_event.pb.h" | 
|  | #include "third_party/metrics_proto/omnibox_scoring_signals.pb.h" | 
|  | #include "third_party/omnibox_proto/answer_type.pb.h" | 
|  | #include "third_party/omnibox_proto/groups.pb.h" | 
|  | #include "third_party/omnibox_proto/navigational_intent.pb.h" | 
|  | #include "third_party/omnibox_proto/rich_answer_template.pb.h" | 
|  | #include "third_party/omnibox_proto/suggest_template_info.pb.h" | 
|  | #include "third_party/omnibox_proto/types.pb.h" | 
|  | #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h" | 
|  | #include "ui/base/page_transition_types.h" | 
|  | #include "ui/gfx/range/range.h" | 
|  | #include "url/gurl.h" | 
|  |  | 
|  | #if BUILDFLAG(IS_ANDROID) | 
|  | #include "base/android/jni_weak_ref.h" | 
|  | #include "base/android/scoped_java_ref.h" | 
|  | #endif | 
|  |  | 
|  | class AutocompleteProvider; | 
|  | class OmniboxAction; | 
|  | class TemplateURL; | 
|  | class TemplateURLService; | 
|  |  | 
|  | namespace base { | 
|  | class Time; | 
|  | }  // namespace base | 
|  |  | 
|  | namespace gfx { | 
|  | struct VectorIcon; | 
|  | }  // namespace gfx | 
|  |  | 
|  | const char kACMatchPropertySuggestionText[] = "match suggestion text"; | 
|  | const char kACMatchPropertyContentsPrefix[] = "match contents prefix"; | 
|  | const char kACMatchPropertyContentsStartIndex[] = "match contents start index"; | 
|  | // A match attribute when a default match's score has been boosted with a higher | 
|  | // scoring non-default match. | 
|  | const char kACMatchPropertyScoreBoostedFrom[] = "score_boosted_from"; | 
|  |  | 
|  | // Util structs/enums ---------------------------------------------------------- | 
|  |  | 
|  | // `RichAutocompletionParams` is a cache for the params used by | 
|  | // `TryRichAutocompletion()`. `TryRichAutocompletion()` is called about 80 times | 
|  | // per keystroke; fetching all 16 params each time causes measurable timing | 
|  | // regressions. Using `static const` local variables instead wouldn't be | 
|  | // testable. | 
|  | struct RichAutocompletionParams { | 
|  | RichAutocompletionParams(); | 
|  | static RichAutocompletionParams& GetParams(); | 
|  | static void ClearParamsForTesting(); | 
|  | bool enabled; | 
|  | size_t autocomplete_titles_min_char; | 
|  | size_t autocomplete_shortcut_text_min_char; | 
|  | }; | 
|  |  | 
|  | struct SessionData { | 
|  | SessionData(); | 
|  | SessionData(const SessionData& session_data); | 
|  | ~SessionData(); | 
|  |  | 
|  | SessionData& operator=(const SessionData& match); | 
|  |  | 
|  | // Whether zero-prefix suggestions could have been shown in the session. | 
|  | bool zero_prefix_enabled = false; | 
|  |  | 
|  | // The number of zero-prefix suggestions shown in the session. | 
|  | size_t num_zero_prefix_suggestions_shown = 0u; | 
|  |  | 
|  | // Whether at least one zero-prefix suggestion was shown in the | 
|  | // session. | 
|  | bool zero_prefix_suggestions_shown_in_session = false; | 
|  |  | 
|  | // Whether at least one typed suggestion was shown in the session. | 
|  | bool typed_suggestions_shown_in_session = false; | 
|  |  | 
|  | // List of GWS event ID hashes accumulated during the course of the session. | 
|  | std::vector<int64_t> gws_event_id_hashes; | 
|  |  | 
|  | // Whether at least one zero-prefix Search/URL suggestion was | 
|  | // shown in the session. This is used in order to ensure that the relevant | 
|  | // client-side metrics logging code emits the proper values. | 
|  | bool zero_prefix_search_suggestions_shown_in_session = false; | 
|  | bool zero_prefix_url_suggestions_shown_in_session = false; | 
|  |  | 
|  | // Whether at least one typed Search/URL suggestion was shown in | 
|  | // the session. This is used in order to ensure that the relevant client-side | 
|  | // metrics logging code emits the proper values. | 
|  | bool typed_search_suggestions_shown_in_session = false; | 
|  | bool typed_url_suggestions_shown_in_session = false; | 
|  |  | 
|  | // Whether at least one contextual search suggestion was shown in the | 
|  | // session. | 
|  | bool contextual_search_suggestions_shown_in_session = false; | 
|  |  | 
|  | // Whether the "Ask Google Lens about this page" action was shown at least | 
|  | // once in the session. | 
|  | bool lens_action_shown_in_session = false; | 
|  | }; | 
|  |  | 
|  | enum class IphType { | 
|  | kNone, | 
|  | // '@gemini' promo; shown in zero state. | 
|  | kGemini, | 
|  | // Enterprise search aggregator promo; shown in zero state. | 
|  | kEnterpriseSearchAggregator, | 
|  | // Featured enterprise site search promo; shown in zero state. | 
|  | kFeaturedEnterpriseSiteSearch, | 
|  | // Embeddings' setting promo when embeddings are disabled; shown in '@history' | 
|  | // scope. | 
|  | kHistoryEmbeddingsSettingsPromo, | 
|  | // Disclaimer when embeddings are enabled; shown in '@history' scope. | 
|  | kHistoryEmbeddingsDisclaimer, | 
|  | // '@history' promo when embeddings are disabled; shown in zero state. | 
|  | kHistoryScopePromo, | 
|  | // '@history' promo when embeddings are enabled; shown in zero state. | 
|  | kHistoryEmbeddingsScopePromo, | 
|  | }; | 
|  |  | 
|  | enum class FeedbackType { | 
|  | kNone, | 
|  | kThumbsUp, | 
|  | kThumbsDown, | 
|  | }; | 
|  |  | 
|  | // Used with `stripped_destination_url` to dedupe matches. Matches with the same | 
|  | // URL but different types won't be deduped. This'll allow showing e.g. both a | 
|  | // "1+1" normal query and a "1+1 = 2" calculator suggestion simultaneously. | 
|  | enum class AutocompleteMatchDedupeType { | 
|  | kNormal, | 
|  | kCalculator,        // E.g. "1+1 = 2" matches. | 
|  | kVerbatimProvider,  // Matches that come from the verbatim provider, which | 
|  | // does not include the verbatim SWYT match. | 
|  | kHistoryEmbeddingAnswer,  // Matches with type `HISTORY_EMBEDDINGS_ANSWER`. | 
|  | kAiMode,  // Matches that activate the DSE's AI Mode. AIM suggestions' URLs | 
|  | // are discerned by a query param `udm=50`. But deduping doesn't | 
|  | // consider extra query params; `google.com/?q=query&udm=50` and | 
|  | // `google.com/?q=query` would usually be deduped. `kAiMode` allows | 
|  | // matches with `udm=50` in their suggest template to not be deduped | 
|  | // with matches without it. But this does not apply to `udm=50` in | 
|  | // the actual match URL; nor to udm values other than 50. | 
|  | }; | 
|  |  | 
|  | // AutocompleteMatch ---------------------------------------------------------- | 
|  |  | 
|  | // A single result line with classified spans.  The autocomplete popup displays | 
|  | // the 'contents' and the 'description' (the description is optional) in the | 
|  | // autocomplete dropdown, and fills in 'fill_into_edit' into the textbox when | 
|  | // that line is selected.  fill_into_edit may be the same as 'description' for | 
|  | // things like URLs, but may be different for searches or other providers.  For | 
|  | // example, a search result may say "Search for asdf" as the description, but | 
|  | // "asdf" should appear in the box. | 
|  | struct AutocompleteMatch { | 
|  | using ScoringSignals = ::metrics::OmniboxScoringSignals; | 
|  |  | 
|  | // Autocomplete matches contain strings that are classified according to a | 
|  | // separate vector of styles.  This vector associates flags with particular | 
|  | // string segments, and must be in sorted order.  All text must be associated | 
|  | // with some kind of classification.  Even if a match has no distinct | 
|  | // segments, its vector should contain an entry at offset 0 with no flags. | 
|  | // | 
|  | // Example: The user typed "goog" | 
|  | //   http://www.google.com/        Google | 
|  | //   ^          ^   ^              ^   ^ | 
|  | //   0,         |   15,            |   4, | 
|  | //              11,match           0,match | 
|  | // | 
|  | // This structure holds the classification information for each span. | 
|  | struct ACMatchClassification { | 
|  | // The values in here are not mutually exclusive -- use them like a | 
|  | // bit field.  This also means we use "int" instead of this enum type when | 
|  | // passing the values around, so the compiler doesn't complain. | 
|  | // | 
|  | // A Java counterpart will be generated for this enum. | 
|  | // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.omnibox | 
|  | // GENERATED_JAVA_CLASS_NAME_OVERRIDE: MatchClassificationStyle | 
|  | // clang-format off | 
|  | enum Style { | 
|  | NONE      = 0, | 
|  | URL       = 1 << 0,  // A URL | 
|  | MATCH     = 1 << 1,  // A match for the user's search term | 
|  | DIM       = 1 << 2,  // "Helper text" | 
|  | TOOLBELT  = 1 << 3,  // Toolbelt label | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | ACMatchClassification() = default; | 
|  | ACMatchClassification(size_t offset, int style) | 
|  | : offset(offset), style(style) {} | 
|  |  | 
|  | friend bool operator==(const ACMatchClassification&, | 
|  | const ACMatchClassification&) = default; | 
|  |  | 
|  | // Offset within the string that this classification starts | 
|  | size_t offset = 0; | 
|  |  | 
|  | // Contains a bitmask of flags defined in enum Style. | 
|  | int style = 0; | 
|  | }; | 
|  |  | 
|  | // SuggestTiles are used specifically with TILE_NAVSUGGEST matches. | 
|  | // This structure should describe only the specific details for individual | 
|  | // tiles; all other properties are considered as shared and should be | 
|  | // extracted from the encompassing AutocompleteMatch object. | 
|  | struct SuggestTile { | 
|  | GURL url{}; | 
|  | std::u16string title{}; | 
|  | bool is_search{}; | 
|  | }; | 
|  |  | 
|  | typedef std::vector<ACMatchClassification> ACMatchClassifications; | 
|  |  | 
|  | // Type used by providers to attach additional, optional information to | 
|  | // an AutocompleteMatch. | 
|  | typedef std::map<std::string, std::string> AdditionalInfo; | 
|  |  | 
|  | // The type of this match. | 
|  | typedef AutocompleteMatchType::Type Type; | 
|  |  | 
|  | // Null-terminated array of characters that are not valid within |contents| | 
|  | // and |description| strings. | 
|  | static const char16_t kInvalidChars[]; | 
|  |  | 
|  | // Document subtype, for AutocompleteMatchType::DOCUMENT. | 
|  | // Update kDocumentTypeStrings when updating DocumentType. | 
|  | enum class DocumentType { | 
|  | NONE = 0, | 
|  | DRIVE_DOCS, | 
|  | DRIVE_FORMS, | 
|  | DRIVE_SHEETS, | 
|  | DRIVE_SLIDES, | 
|  | DRIVE_IMAGE, | 
|  | DRIVE_PDF, | 
|  | DRIVE_VIDEO, | 
|  | DRIVE_FOLDER, | 
|  | DRIVE_OTHER, | 
|  | DOCUMENT_TYPE_SIZE | 
|  | }; | 
|  |  | 
|  | // Enterprise search aggregator subtype, for suggestions from the | 
|  | // EnterpriseSearchAggregatorProvider provider. | 
|  | enum class EnterpriseSearchAggregatorType { | 
|  | NONE = 0, | 
|  | QUERY, | 
|  | PEOPLE, | 
|  | CONTENT, | 
|  | }; | 
|  |  | 
|  | // These values are persisted to logs. Entries should not be renumbered and | 
|  | // numeric values should never be reused. | 
|  | enum class RichAutocompletionType { | 
|  | kNone = 0, | 
|  | // kUrlNonPrefix = 1, // deprecated | 
|  | kTitlePrefix = 2, | 
|  | // kTitleNonPrefix = 3, // deprecated | 
|  | kShortcutTextPrefix = 4, | 
|  | kMaxValue = kShortcutTextPrefix, | 
|  | }; | 
|  |  | 
|  | static constexpr auto kDocumentTypeStrings = std::to_array<const char*>( | 
|  | {"none", "drive_docs", "drive_forms", "drive_sheets", "drive_slides", | 
|  | "drive_image", "drive_pdf", "drive_video", "drive_folder", | 
|  | "drive_other"}); | 
|  |  | 
|  | static_assert(kDocumentTypeStrings.size() == | 
|  | static_cast<int>(DocumentType::DOCUMENT_TYPE_SIZE), | 
|  | "Sizes of AutocompleteMatch::kDocumentTypeStrings and " | 
|  | "AutocompleteMatch::DocumentType don't match."); | 
|  |  | 
|  | // Return a string version of the core type values. Only used for | 
|  | // `RecordAdditionalInfo()`. | 
|  | static const char* DocumentTypeString(DocumentType type); | 
|  |  | 
|  | // Use this function to convert integers to DocumentType enum values. | 
|  | // If you're sure it will be valid, you can call CHECK on the return value. | 
|  | // Returns true if |value| was successfully converted to a valid enum value. | 
|  | // The valid enum value will be written into |result|. | 
|  | static bool DocumentTypeFromInteger(int value, DocumentType* result); | 
|  |  | 
|  | AutocompleteMatch(); | 
|  | AutocompleteMatch(AutocompleteProvider* provider, | 
|  | int relevance, | 
|  | bool deletable, | 
|  | Type type); | 
|  | AutocompleteMatch(const AutocompleteMatch& match); | 
|  | AutocompleteMatch(AutocompleteMatch&& match) noexcept; | 
|  | ~AutocompleteMatch(); | 
|  |  | 
|  | AutocompleteMatch& operator=(const AutocompleteMatch& match); | 
|  | AutocompleteMatch& operator=(AutocompleteMatch&& match) noexcept; | 
|  |  | 
|  | #if BUILDFLAG(IS_ANDROID) | 
|  | // Returns a corresponding Java object, creating it if necessary. | 
|  | // NOTE: Android specific methods are defined in autocomplete_match_android.cc | 
|  | base::android::ScopedJavaLocalRef<jobject> GetOrCreateJavaObject( | 
|  | JNIEnv* env) const; | 
|  |  | 
|  | // Update the bond with- or drop the Java AutocompleteMatch instance. | 
|  | // This should be called whenever the native AutocompleteMatch object is | 
|  | // updated for an existing Java object. | 
|  | void UpdateJavaObjectNativeRef(); | 
|  |  | 
|  | // Notify the Java object that its native counterpart is about to be | 
|  | // destroyed. | 
|  | void DestroyJavaObject(); | 
|  |  | 
|  | // Returns a corresponding Java Class object. | 
|  | static jclass GetClazz(JNIEnv* env); | 
|  |  | 
|  | // Update the clipboard match with the current clipboard data. | 
|  | void UpdateWithClipboardContent( | 
|  | JNIEnv* env, | 
|  | const base::android::JavaParamRef<jobject>& j_callback); | 
|  |  | 
|  | // Called when the match is updated with the clipboard content. | 
|  | void OnClipboardSuggestionContentUpdated( | 
|  | const base::android::JavaRef<jobject>& j_callback); | 
|  |  | 
|  | // Update the Java object with clipboard content. | 
|  | void UpdateClipboardContent(JNIEnv* env); | 
|  | // Update the Java object with new destination URL. | 
|  | void UpdateJavaNavigationDetails(); | 
|  | // Update the Java object with new Answer-in-Suggest. | 
|  | void UpdateJavaAnswer(); | 
|  | // Update the Java object description. | 
|  | void UpdateJavaDescription(); | 
|  | #endif | 
|  |  | 
|  | #if (!BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !BUILDFLAG(IS_IOS) | 
|  | // Converts omnibox::AnswerType to an answer vector icon. | 
|  | static const gfx::VectorIcon& AnswerTypeToAnswerIcon( | 
|  | omnibox::AnswerType type); | 
|  |  | 
|  | // Gets the vector icon identifier for the icon to be shown for this match. If | 
|  | // `is_bookmark` is true, returns a bookmark icon rather than what the type | 
|  | // would normally determine.  Note that in addition to `type`, the icon chosen | 
|  | // may depend on match contents (e.g. Drive `document_type` or `actions`). | 
|  | // The reason `is_bookmark` is passed as a parameter and is not baked into the | 
|  | // AutocompleteMatch is likely that 1) this info is not used elsewhere in the | 
|  | // Autocomplete machinery except before displaying the match and 2) obtaining | 
|  | // this info is trivially done by calling BookmarkModel::IsBookmarked(). | 
|  | // `turl` is used to identify the proper vector icon associated with a given | 
|  | // starter pack suggestion (e.g. @tabs, @history, @bookmarks, etc.). | 
|  | const gfx::VectorIcon& GetVectorIcon(bool is_bookmark, | 
|  | const TemplateURL* turl = nullptr) const; | 
|  | #endif | 
|  |  | 
|  | // Comparison function for determining whether the first match is better than | 
|  | // the second. | 
|  | static bool MoreRelevant(const AutocompleteMatch& match1, | 
|  | const AutocompleteMatch& match2); | 
|  |  | 
|  | // Comparison functions for determining whether the first match is preferred | 
|  | // over the second when choosing between candidate duplicates. | 
|  | static bool BetterDuplicate(const AutocompleteMatch& match1, | 
|  | const AutocompleteMatch& match2); | 
|  | static bool BetterDuplicateByIterator( | 
|  | const std::vector<AutocompleteMatch>::const_iterator it1, | 
|  | const std::vector<AutocompleteMatch>::const_iterator it2); | 
|  |  | 
|  | // Returns a new vector of classifications containing the merged contents of | 
|  | // |classifications1| and |classifications2|. | 
|  | static ACMatchClassifications MergeClassifications( | 
|  | const ACMatchClassifications& classifications1, | 
|  | const ACMatchClassifications& classifications2); | 
|  |  | 
|  | // Converts classifications to and from a serialized string representation | 
|  | // (using comma-separated integers to sequentially list positions and styles). | 
|  | static std::string ClassificationsToString( | 
|  | const ACMatchClassifications& classifications); | 
|  | static ACMatchClassifications ClassificationsFromString( | 
|  | const std::string& serialized_classifications); | 
|  |  | 
|  | // Adds a classification to the end of |classifications| iff its style is | 
|  | // different from the last existing classification.  |offset| must be larger | 
|  | // than the offset of the last classification in |classifications|. | 
|  | static void AddLastClassificationIfNecessary( | 
|  | ACMatchClassifications* classifications, | 
|  | size_t offset, | 
|  | int style); | 
|  |  | 
|  | // Removes invalid characters from |text|. Should be called on strings coming | 
|  | // from external sources (such as extensions) before assigning to |contents| | 
|  | // or |description|. | 
|  | static std::u16string SanitizeString(const std::u16string& text); | 
|  |  | 
|  | // Convenience function to check if `type` is featured Enterprise search. | 
|  | static bool IsFeaturedEnterpriseSearchType(Type type); | 
|  |  | 
|  | // Convenience function to check if `type` is featured search type, e.g. | 
|  | // starter pack and featured site search engines created by policy. | 
|  | static bool IsFeaturedSearchType(Type type); | 
|  |  | 
|  | // Convenience function to check if `type` is preconnectable. | 
|  | // Preconnecting allows connecting to an origin before requesting any | 
|  | // resources from that origin, effectively "warming up" the connection. When a | 
|  | // resource from that origin is requested, we can immediately use the | 
|  | // established connection, saving valuable round-trips. This differs from | 
|  | // preloading and prefetching in that it does not actually fetch any resources | 
|  | // from the origin, it just establishes the connection to the origin earlier. | 
|  | static bool IsPreconnectableType(Type type); | 
|  |  | 
|  | // Convenience function to check if |type| is a search (as opposed to a URL or | 
|  | // an extension). | 
|  | static bool IsSearchType(Type type); | 
|  |  | 
|  | // Convenience function to check if |type| is a special search suggest type - | 
|  | // like entity, personalized, profile or postfix. | 
|  | static bool IsSpecializedSearchType(Type type); | 
|  |  | 
|  | // Convenience function to check if |type| is a search history type - | 
|  | // usually this surfaces a clock icon to the user. | 
|  | static bool IsSearchHistoryType(Type type); | 
|  |  | 
|  | // Returns whether this match is a starter pack suggestion provided by the | 
|  | // built-in provider. This is the suggestion that the starter pack keyword | 
|  | // mode chips attach to. | 
|  | static bool IsStarterPackType(Type type); | 
|  |  | 
|  | // Returns whether this match is a Clipboard suggestion. | 
|  | static bool IsClipboardType(Type type); | 
|  |  | 
|  | // Convenience function to check if |type| is one of the suggest types we | 
|  | // need to skip for search vs url partitions - url, text or image in the | 
|  | // clipboard or query tile. | 
|  | static bool ShouldBeSkippedForGroupBySearchVsUrl(Type type); | 
|  |  | 
|  | // Return a group ID based on type. Should only be used as a fill in for | 
|  | // matches that don't already have a group ID set by providers. | 
|  | static omnibox::GroupId GetDefaultGroupId(Type type); | 
|  |  | 
|  | // A static version GetTemplateURL() that takes the match's keyword and | 
|  | // match's hostname as parameters.  In short, returns the TemplateURL | 
|  | // associated with |keyword| if it exists; otherwise returns the TemplateURL | 
|  | // associated with |host| if it exists. | 
|  | static TemplateURL* GetTemplateURLWithKeyword( | 
|  | TemplateURLService* template_url_service, | 
|  | const std::u16string& keyword, | 
|  | const std::string& host); | 
|  | static const TemplateURL* GetTemplateURLWithKeyword( | 
|  | const TemplateURLService* template_url_service, | 
|  | const std::u16string& keyword, | 
|  | const std::string& host); | 
|  |  | 
|  | // Returns `url` altered by stripping off "www.", converting https protocol | 
|  | // to http, and stripping query params other than the search terms. If | 
|  | // `keep_search_intent_params` is true, also keep search intent params which | 
|  | // disambiguate the search terms and determine the fulfillment. | 
|  | // These conversions are meant to allow URL comparisons to find likely | 
|  | // duplicates; and these URLs are not used as actual destination URLs. | 
|  | // In most use cases `keep_search_intent_params` need not be true, e.g., when | 
|  | // computing `stripped_destination_url` for matches. Otherwise, keeping the | 
|  | // search intent params would create an unnecessary level of granularity which | 
|  | // prevents proper deduping of matches from various local or remote providers. | 
|  | // If a provider wishes to prevent its matches (or a subset of them) from | 
|  | // being deduped with other matches with the same search terms, it must | 
|  | // precompute `stripped_destination_url` while maintaining the search intent | 
|  | // params. A notable example is when multiple entity suggestions with the same | 
|  | // search terms are offered by SearchProvider or ZeroSuggestProvider. In that | 
|  | // case, the entity matches (with the exception of the first one) keep their | 
|  | // search intent params in `stripped_destination_url` to avoid being deduped. | 
|  | // - `input` is used to decide if the scheme is allowed to be altered during | 
|  | //   stripping.  If this URL, minus the scheme and separator, starts with any | 
|  | //   the terms in input.terms_prefixed_by_http_or_https(), we avoid converting | 
|  | //   an HTTPS scheme to HTTP.  This means URLs that differ only by these | 
|  | //   schemes won't be marked as dupes, since the distinction seems to matter | 
|  | //   to the user. | 
|  | // - If `template_url_service` is not NULL, it is used to get a template URL | 
|  | //   corresponding to this match, which is used to strip off query params | 
|  | //   other than the search terms (and optionally search intent params) that | 
|  | //   would otherwise prevent proper comparison/deduping. | 
|  | // - If the match's keyword is known, it can be provided in `keyword`. | 
|  | //   Otherwise, it can be left empty and the template URL (if any) is | 
|  | //   determined from the destination's hostname. | 
|  | static GURL GURLToStrippedGURL(const GURL& url, | 
|  | const AutocompleteInput& input, | 
|  | const TemplateURLService* template_url_service, | 
|  | const std::u16string& keyword, | 
|  | const bool keep_search_intent_params); | 
|  |  | 
|  | // Sets the |match_in_scheme| and |match_in_subdomain| flags based on the | 
|  | // provided |url| and list of substring |match_positions|. |match_positions| | 
|  | // is the [begin, end) positions of a match within the unstripped URL spec. | 
|  | using MatchPosition = std::pair<size_t, size_t>; | 
|  | static void GetMatchComponents( | 
|  | const GURL& url, | 
|  | const std::vector<MatchPosition>& match_positions, | 
|  | bool* match_in_scheme, | 
|  | bool* match_in_subdomain); | 
|  |  | 
|  | // Gets the formatting flags used for display of suggestions. This method | 
|  | // encapsulates the return of experimental flags too, so any URLs displayed | 
|  | // as an Omnibox suggestion should use this method. | 
|  | // | 
|  | // This function returns flags that may destructively format the URL, and | 
|  | // therefore should never be used for the |fill_into_edit| field. | 
|  | // | 
|  | // |preserve_scheme| and |preserve_subdomain| indicate that these URL | 
|  | // components are important (part of the match), and should not be trimmed. | 
|  | static url_formatter::FormatUrlTypes GetFormatTypes(bool preserve_scheme, | 
|  | bool preserve_subdomain); | 
|  | // Logs the search engine used to navigate to a search page or auto complete | 
|  | // suggestion. For direct URL navigations, nothing is logged. | 
|  | static void LogSearchEngineUsed(const AutocompleteMatch& match, | 
|  | TemplateURLService* template_url_service); | 
|  |  | 
|  | // Computes the stripped destination URL (via GURLToStrippedGURL()) and | 
|  | // stores the result in |stripped_destination_url|.  |input| is used for the | 
|  | // same purpose as in GURLToStrippedGURL(). | 
|  | void ComputeStrippedDestinationURL(const AutocompleteInput& input, | 
|  | TemplateURLService* template_url_service); | 
|  |  | 
|  | // Returns whether `destination_url` looks like a doc URL. If so, will also | 
|  | // set `stripped_destination_url` to avoid repeating the computation later. | 
|  | bool IsDocumentSuggestion(); | 
|  |  | 
|  | // Checks if this match is a trend suggestion based on the match subtypes. | 
|  | bool IsTrendSuggestion() const; | 
|  |  | 
|  | // Checks if this match is an informational IPH suggestion based on the match | 
|  | // and provider type. | 
|  | bool IsIphSuggestion() const; | 
|  |  | 
|  | // Checks if this match has an attached action with the given `action_id`. | 
|  | bool HasAction(OmniboxActionId action_id) const; | 
|  |  | 
|  | // Checks if this match is a contextual search suggestion to be fulfilled | 
|  | // by lens in the side panel. | 
|  | bool IsContextualSearchSuggestion() const; | 
|  |  | 
|  | // Checks if this match is a specialized toolbelt match with actions on | 
|  | // a button row. | 
|  | bool IsToolbelt() const; | 
|  |  | 
|  | // Checks if this match is a AI mode suggestion. | 
|  | bool IsSearchAimSuggestion() const; | 
|  |  | 
|  | // Checks if this match has a Lens search action. | 
|  | bool HasLensSearchAction() const; | 
|  |  | 
|  | // Returns true if this match may attach one or more `actions`. | 
|  | // This method is used to keep actions off of matches with types that don't | 
|  | // mix well with Pedals or other actions (e.g. entities). | 
|  | bool IsActionCompatible() const; | 
|  |  | 
|  | // Returns true if this match has a keyword that puts the omnibox instantly | 
|  | // into keyword mode when the match is focused via keyboard, instead of | 
|  | // the usual waiting for activation of a visible keyword button. | 
|  | bool HasInstantKeyword(const TemplateURLService* template_url_service) const; | 
|  |  | 
|  | // Gets data relevant to whether there should be any special keyword-related | 
|  | // UI shown for this match. If this match represents a selected keyword, i.e. | 
|  | // the UI should be "in keyword mode", `keyword_out` will be set to the | 
|  | // keyword and `is_keyword_hint` will be set to false. If this match has a | 
|  | // non-null `associated_keyword`, i.e. we should show a "Press [tab] to search | 
|  | // ___" hint and allow the user to toggle into keyword mode, `keyword_out` | 
|  | // will be set to the associated keyword and `is_keyword_hint` will be set to | 
|  | // true. Note that only one of these states can be in effect at once. In all | 
|  | // other cases, `keyword_out` will be cleared, even when our member variable | 
|  | // `keyword` is non-empty -- such as with non-substituting keywords or matches | 
|  | // that represent searches using the default search engine. See also | 
|  | // `GetSubstitutingExplicitlyInvokedKeyword()`. `keyword_placeholder_out` will | 
|  | // be set to any placeholder text the keyword wants to display. Set for both | 
|  | // hint and non-hint keyword modes. `is_history_embeddings_enabled` will | 
|  | // affect the placeholder text for the @history keyword. | 
|  | void GetKeywordUIState(TemplateURLService* template_url_service, | 
|  | bool is_history_embeddings_enabled, | 
|  | std::u16string* keyword_out, | 
|  | std::u16string* keyword_placeholder_out, | 
|  | bool* is_keyword_hint) const; | 
|  |  | 
|  | // Returns |keyword|, but only if it represents a substituting keyword that | 
|  | // the user has explicitly invoked.  If for example this match represents a | 
|  | // search with the default search engine (and the user didn't explicitly | 
|  | // invoke its keyword), this returns the empty string.  The result is that | 
|  | // this function returns a non-empty string in the same cases as when the UI | 
|  | // should show up as being "in keyword mode". | 
|  | std::u16string GetSubstitutingExplicitlyInvokedKeyword( | 
|  | TemplateURLService* template_url_service) const; | 
|  |  | 
|  | // Returns the placeholder text to display for the given starter pack keyword | 
|  | // TemplateURL, returned for both hint and non-hint keyword modes. | 
|  | // The `template_url` may be nullptr and this method often defaults to | 
|  | // returning the empty string. | 
|  | static std::u16string GetKeywordPlaceholder( | 
|  | const TemplateURL* template_url, | 
|  | bool is_history_embeddings_enabled); | 
|  |  | 
|  | // Returns the `TemplateURL` associated with this match. This may be nullptr | 
|  | // if the match has no keyword OR if the keyword no longer corresponds to a | 
|  | // valid `TemplateURL`. See comments on `keyword` below. | 
|  | TemplateURL* GetTemplateURL(TemplateURLService* template_url_service) const; | 
|  |  | 
|  | // Gets the URL for the match image (whether it be an answer or entity). If | 
|  | // there isn't an image URL, returns an empty GURL (test with is_empty()). | 
|  | GURL ImageUrl() const; | 
|  |  | 
|  | // Adds optional information to the |additional_info| dictionary. | 
|  | void RecordAdditionalInfo(const std::string& property, | 
|  | const std::string& value); | 
|  | void RecordAdditionalInfo(const std::string& property, | 
|  | const std::u16string& value); | 
|  | void RecordAdditionalInfo(const std::string& property, int value); | 
|  | void RecordAdditionalInfo(const std::string& property, double value); | 
|  | void RecordAdditionalInfo(const std::string& property, base::Time value); | 
|  |  | 
|  | // Returns the value recorded for |property| in the |additional_info| | 
|  | // dictionary. Returns the empty string if no such value exists. This is for | 
|  | // debugging in chrome://omnibox only. It should only be called by | 
|  | // `OmniboxPageHandler` and tests. For match info that's used for | 
|  | // non-debugging, use class fields. Unfortunately, There are existing | 
|  | // non-debug callsites; those should be cleaned up, not added to. | 
|  | std::string GetAdditionalInfoForDebugging(const std::string& property) const; | 
|  |  | 
|  | // Returns the provider type selected from this match, which is by default | 
|  | // taken from the match `provider` type but may be a (pseudo-)provider | 
|  | // associated with one of the match's action types if one of the match's | 
|  | // actions are chosen with `action_index`. | 
|  | metrics::OmniboxEventProto::ProviderType GetOmniboxEventProviderType( | 
|  | int action_index = -1) const; | 
|  |  | 
|  | // Returns the result type selected from this match, which is by default | 
|  | // equivalent to the match type but may be one of the match's action | 
|  | // types if one of the match's actions are chosen with `action_index`. | 
|  | metrics::OmniboxEventProto::Suggestion::ResultType GetOmniboxEventResultType( | 
|  | int action_index = -1) const; | 
|  |  | 
|  | // Returns whether this match is a "verbatim" match: a URL navigation directly | 
|  | // to the user's input, a search for the user's input with the default search | 
|  | // engine, or a "keyword mode" search for the query portion of the user's | 
|  | // input.  Note that rare or unusual types that could be considered verbatim, | 
|  | // such as keyword engine matches or extension-provided matches, aren't | 
|  | // detected by this IsVerbatimType, as the user will not be able to infer | 
|  | // what will happen when they press enter in those cases if the match is not | 
|  | // shown. | 
|  | bool IsVerbatimType() const; | 
|  |  | 
|  | // Returns whether this match is a "verbatim URL" suggestion. | 
|  | bool IsVerbatimUrlSuggestion() const; | 
|  |  | 
|  | // Returns whether this match is a search suggestion provided by search | 
|  | // provider. | 
|  | bool IsSearchProviderSearchSuggestion() const; | 
|  |  | 
|  | // Returns whether this match is a search suggestion provided by on device | 
|  | // providers. | 
|  | bool IsOnDeviceSearchSuggestion() const; | 
|  |  | 
|  | // Returns the top-level sorting order of the suggestion. | 
|  | // Suggestions should be sorted by this value first, and by Relevance score | 
|  | // next. | 
|  | int GetSortingOrder() const; | 
|  |  | 
|  | // Whether this autocomplete match supports custom descriptions. | 
|  | bool HasCustomDescription() const; | 
|  |  | 
|  | // Returns true if the match is eligible for ML scoring signal logging. | 
|  | bool IsMlSignalLoggingEligible() const; | 
|  |  | 
|  | // Returns true if the match is eligible to be re-scored by ML scoring. | 
|  | bool IsMlScoringEligible() const; | 
|  |  | 
|  | // Filter OmniboxActions based on the supplied qualifiers. | 
|  | // The order of the supplied qualifiers determines the preference. | 
|  | void FilterOmniboxActions( | 
|  | const std::vector<OmniboxActionId>& allowed_action_ids); | 
|  |  | 
|  | // Rearranges and truncates ActionsInSuggest objects to match the desired | 
|  | // order and presence of actions. | 
|  | // Unlike FilterOmniboxActions(), this method specifically targets | 
|  | // ActionsInSuggest. | 
|  | void FilterAndSortActionsInSuggest(); | 
|  |  | 
|  | // Remove all Answer Actions. | 
|  | void RemoveAnswerActions(); | 
|  |  | 
|  | // Returns whether the autocompletion is trivial enough that we consider it | 
|  | // an autocompletion for which the omnibox autocompletion code did not add | 
|  | // any value. | 
|  | bool IsTrivialAutocompletion() const; | 
|  |  | 
|  | // Returns whether this match or any duplicate of this match can be deleted. | 
|  | // This is used to decide whether we should call DeleteMatch(). | 
|  | bool SupportsDeletion() const; | 
|  |  | 
|  | // Returns a copy of this match with the contents and description fields, and | 
|  | // their associated classifications, possibly swapped.  We swap these if this | 
|  | // is a match for which we should emphasize the title (stored in the | 
|  | // description field) over the URL (in the contents field). | 
|  | // | 
|  | // We specifically return a copy to prevent the UI code from accidentally | 
|  | // mucking with the matches stored in the model, lest other omnibox systems | 
|  | // get confused about which is which.  See the code that sets | 
|  | // |swap_contents_and_description| for conditions they are swapped. | 
|  | // | 
|  | // TODO(crbug.com/40179316): Clean up the handling of contents and description | 
|  | // so that this copy is no longer required. | 
|  | AutocompleteMatch GetMatchWithContentsAndDescriptionPossiblySwapped() const; | 
|  |  | 
|  | // Determines whether this match is allowed to be the default match by | 
|  | // comparing |input.text| and |inline_autocompletion|. Therefore, | 
|  | // |inline_autocompletion| should be set prior to invoking this method. Also | 
|  | // considers trailing whitespace in the input, so the input should not be | 
|  | // fixed up. May trim trailing whitespaces from |inline_autocompletion|. | 
|  | // | 
|  | // Input "x" will allow default matches "x", "xy", and "x y". | 
|  | // Input "x " will allow default matches "x" and "x y". | 
|  | // Input "x  " will allow default match "x". | 
|  | // Input "x y" will allow default match "x y". | 
|  | // Input "x" with prevent_inline_autocomplete will allow default match "x". | 
|  | void SetAllowedToBeDefault(const AutocompleteInput& input); | 
|  |  | 
|  | // Estimates dynamic memory usage. | 
|  | // See base/trace_event/memory_usage_estimator.h for more info. | 
|  | size_t EstimateMemoryUsage() const; | 
|  |  | 
|  | // Upgrades this match by absorbing the best properties from | 
|  | // |duplicate_match|. For instance: if |duplicate_match| has a higher | 
|  | // relevance score, this match's own relevance score will be upgraded. | 
|  | void UpgradeMatchWithPropertiesFrom(AutocompleteMatch& duplicate_match); | 
|  |  | 
|  | // Merges scoring signals from the other match for ML model scoring and | 
|  | // training . | 
|  | void MergeScoringSignals(const AutocompleteMatch& other); | 
|  |  | 
|  | // Tries, in order, to: | 
|  | // - Prefix autocomplete |primary_text| | 
|  | // - Prefix autocomplete |secondary_text| | 
|  | // - Non-prefix autocomplete |primary_text| | 
|  | // - Non-prefix autocomplete |secondary_text| | 
|  | // - Split autocomplete |primary_text| | 
|  | // - Split autocomplete |secondary_text| | 
|  | // Returns false if none of the autocompletions were appropriate (or the | 
|  | // features were disabled). | 
|  | bool TryRichAutocompletion(const AutocompleteInput& input, | 
|  | const std::u16string& primary_text, | 
|  | const std::u16string& secondary_text, | 
|  | const std::u16string& shortcut_text = u""); | 
|  |  | 
|  | // Serialise this object into a trace. | 
|  | void WriteIntoTrace(perfetto::TracedValue context) const; | 
|  |  | 
|  | // Returns the action at `index`, or nullptr if `index` is out of bounds. | 
|  | OmniboxAction* GetActionAt(size_t index) const; | 
|  |  | 
|  | // Returns if `predicate` returns true for the match or one of its duplicates. | 
|  | template <typename UnaryPredicate> | 
|  | bool MatchOrDuplicateMeets(UnaryPredicate predicate) const { | 
|  | return predicate(*this) || | 
|  | std::ranges::any_of(duplicate_matches, std::move(predicate)); | 
|  | } | 
|  |  | 
|  | // Finds first action where `predicate` returns true. This is a special use | 
|  | // utility method for situations where actions with certain constraints | 
|  | // need to be selected. If no such action is found, returns nullptr. | 
|  | template <typename UnaryPredicate> | 
|  | OmniboxAction* GetActionWhere(UnaryPredicate predicate) const { | 
|  | auto it = std::ranges::find_if(actions, std::move(predicate)); | 
|  | return it != actions.end() ? it->get() : nullptr; | 
|  | } | 
|  |  | 
|  | // Returns true if this match has a `takeover_action` with given `id`. | 
|  | bool HasTakeoverAction(OmniboxActionId id) const; | 
|  |  | 
|  | // Create a new match from scratch based on this match and its action at | 
|  | // given `action_index`. The content and takeover match on the returned | 
|  | // match will be set up to execute the action, and only a minimum of | 
|  | // data is shared from this source match. | 
|  | AutocompleteMatch CreateActionMatch(size_t action_index) const; | 
|  |  | 
|  | // The provider of this match, used to remember which provider the user had | 
|  | // selected when the input changes. This may be NULL, in which case there is | 
|  | // no provider (or memory of the user's selection). | 
|  | raw_ptr<AutocompleteProvider> provider = nullptr; | 
|  |  | 
|  | // The relevance of this match. See table in autocomplete_provider.h for | 
|  | // scores returned by various providers. This is used to rank matches among | 
|  | // all responding providers, so different providers must be carefully tuned to | 
|  | // supply matches with appropriate relevance. | 
|  | int relevance = 0; | 
|  |  | 
|  | // The "navigational intent" of this match. In other words, the likelihood | 
|  | // that the user intends to navigate to a specific place by making use of | 
|  | // this match. | 
|  | omnibox::NavigationalIntent navigational_intent{omnibox::NAV_INTENT_NONE}; | 
|  |  | 
|  | // How many times this result was typed in / selected from the omnibox. | 
|  | // Only set for some providers and result_types.  If it is not set, | 
|  | // its value is -1.  At the time of writing this comment, it is only | 
|  | // set for matches from HistoryURL and HistoryQuickProvider. | 
|  | int typed_count = -1; | 
|  |  | 
|  | // True if the user should be able to delete this match. | 
|  | bool deletable = false; | 
|  |  | 
|  | // This string is loaded into the location bar when the item is selected | 
|  | // by pressing the arrow keys. This may be different than a URL, for example, | 
|  | // for search suggestions, this would just be the search terms. | 
|  | std::u16string fill_into_edit; | 
|  |  | 
|  | // This string is displayed adjacent to the omnibox if this match is the | 
|  | // default. Will usually be URL when autocompleting a title, and empty | 
|  | // otherwise. | 
|  | std::u16string additional_text; | 
|  |  | 
|  | // The inline autocompletion to display after the user's input in the | 
|  | // omnibox, if this match becomes the default match.  It may be empty. | 
|  | std::u16string inline_autocompletion; | 
|  | // Whether rich autocompletion triggered; i.e. this suggestion *is or could | 
|  | // have been* rich autocompleted. | 
|  | // TODO(manukh): remove `rich_autocompletion_triggered` when counterfactual | 
|  | //  experiments end. | 
|  | RichAutocompletionType rich_autocompletion_triggered = | 
|  | RichAutocompletionType::kNone; | 
|  |  | 
|  | // If false, the omnibox should prevent this match from being the | 
|  | // default match.  Providers should set this to true only if the | 
|  | // user's input, plus any inline autocompletion on this match, would | 
|  | // lead the user to expect a navigation to this match's destination. | 
|  | // For example, with input "foo", a search for "bar" or navigation | 
|  | // to "bar.com" should not set this flag; a navigation to "foo.com" | 
|  | // should only set this flag if ".com" will be inline autocompleted; | 
|  | // and a navigation to "foo/" (an intranet host) or search for "foo" | 
|  | // should set this flag. | 
|  | bool allowed_to_be_default_match = false; | 
|  |  | 
|  | // The URL to actually load when the autocomplete item is selected. This URL | 
|  | // should be canonical so we can compare URLs with strcmp to avoid dupes. | 
|  | // It may be empty if there is no possible navigation. | 
|  | GURL destination_url; | 
|  |  | 
|  | // The destination URL modified for better dupe finding.  The result may not | 
|  | // be navigable or even valid; it's only meant to be used for detecting | 
|  | // duplicates. Providers are not expected to set this field, | 
|  | // `AutocompleteResult` will set it using `ComputeStrippedDestinationURL()`. | 
|  | // Providers may manually set it to avoid the default | 
|  | // `ComputeStrippedDestinationURL()` computation. | 
|  | GURL stripped_destination_url; | 
|  |  | 
|  | // Extra headers to add to the navigation. Keys of the map represent the | 
|  | // header name, and values represent header value, e.g. | 
|  | //   extra_headers["Content-Type"] = "application/json"; | 
|  | std::map<std::string, std::string> extra_headers; | 
|  |  | 
|  | // Optional image information. Used for some types of suggestions, such as | 
|  | // entity suggestions, that want to display an associated image, which will be | 
|  | // rendered larger than a regular suggestion icon. | 
|  | // The dominant color can be used to paint an image placeholder while fetching | 
|  | // the image. The value is a hex string (for example, "#424242"). | 
|  | std::string image_dominant_color; | 
|  | GURL image_url; | 
|  |  | 
|  | // Optional icon URL. Providers may set this to override the default icon for | 
|  | // the match. | 
|  | GURL icon_url; | 
|  |  | 
|  | // Optional entity id for entity suggestions. Empty string means no entity ID. | 
|  | // This is not meant for display, but internal use only. The actual UI display | 
|  | // is controlled by the `type` and `image_url`. | 
|  | std::string entity_id; | 
|  |  | 
|  | // Optional website URI for entity suggestions. Empty string means no website | 
|  | // URI. | 
|  | std::string website_uri; | 
|  |  | 
|  | // Used for document suggestions to show the mime-corresponding icons. | 
|  | DocumentType document_type = DocumentType::NONE; | 
|  |  | 
|  | // Used for enterprise search aggregator suggestions for grouping. | 
|  | EnterpriseSearchAggregatorType enterprise_search_aggregator_type = | 
|  | EnterpriseSearchAggregatorType::NONE; | 
|  |  | 
|  | // Holds the common part of tail suggestion. Used to indent the contents. | 
|  | // Can't simply store the character length of the string, as different | 
|  | // characters may have different rendered widths. | 
|  | std::u16string tail_suggest_common_prefix; | 
|  |  | 
|  | // The main text displayed in the address bar dropdown. | 
|  | std::u16string contents; | 
|  | ACMatchClassifications contents_class; | 
|  |  | 
|  | // Additional helper text for each entry, such as a title or description. | 
|  | std::u16string description; | 
|  | ACMatchClassifications description_class; | 
|  | // In the case of the document provider, `description` includes a last | 
|  | // updated date that may become stale. Likewise for the bookmark provider, | 
|  | // `contents` may be the path which may become stale when the bookmark is | 
|  | // moved. To avoid showing stale text, when `description_for_shortcut` | 
|  | // is not empty, it will be stored instead of `description` (or `contents` if | 
|  | // `swap_contents_and_description` is true) in the shortcuts provider. | 
|  | // TODO(manukh) This is a temporary misnomer (since it can represent both | 
|  | //   `description` and `contents`) until `swap_contents_and_description` is | 
|  | //   removed. | 
|  | std::u16string description_for_shortcuts; | 
|  | ACMatchClassifications description_class_for_shortcuts; | 
|  |  | 
|  | // The optional suggestion group ID used to look up the suggestion group info | 
|  | // for the group this suggestion belongs to from the AutocompleteResult. | 
|  | // | 
|  | // Use omnibox::GROUP_INVALID in place of a missing value when converting | 
|  | // this to a primitive type. | 
|  | // TODO(manukh): Seems redundant to prefix a suggestion field with | 
|  | //  'suggestion_'. Check if it makes sense to rename to 'group_id', and | 
|  | //  likewise for the associated methods and local variables. | 
|  | std::optional<omnibox::GroupId> suggestion_group_id; | 
|  |  | 
|  | // If true, UI-level code should swap the contents and description fields | 
|  | // before displaying. | 
|  | bool swap_contents_and_description = false; | 
|  |  | 
|  | std::optional<omnibox::RichAnswerTemplate> answer_template; | 
|  |  | 
|  | std::optional<omnibox::SuggestTemplateInfo> suggest_template; | 
|  |  | 
|  | // AnswerType for answer verticals, including rich answers. | 
|  | omnibox::AnswerType answer_type{omnibox::ANSWER_TYPE_UNSPECIFIED}; | 
|  |  | 
|  | // The transition type to use when the user opens this match.  By default, | 
|  | // this is TYPED.  Providers whose matches do not look like URLs should set | 
|  | // it to GENERATED. | 
|  | ui::PageTransition transition = ui::PAGE_TRANSITION_TYPED; | 
|  |  | 
|  | // Type of this match. | 
|  | Type type = AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED; | 
|  |  | 
|  | // The type of this suggestion as reported from and back to the suggest server | 
|  | // via the server response and the ChromeSearchboxStats (reported in the match | 
|  | // destination URL) respectively. | 
|  | // The default value indicates a native Chrome suggestion which must include a | 
|  | // SUBTYPE_OMNIBOX_* in `subtypes`. | 
|  | // | 
|  | // The value is always present in omnibox::SuggestType enum. Although the list | 
|  | // of types in omnibox::SuggestType enum may not be exhaustive, the known type | 
|  | // names found in the server response are mapped to the equivalent enum values | 
|  | // and the unknown types fall back to omnibox::TYPE_QUERY. | 
|  | omnibox::SuggestType suggest_type{omnibox::TYPE_NATIVE_CHROME}; | 
|  |  | 
|  | // Used to identify the specific source / type for suggestions by the | 
|  | // suggest server. See SuggestSubtype in types.proto for more details. | 
|  | // Uses flat_set to deduplicate subtypes (e.g., as a result of Chrome adding | 
|  | // additional subtypes). The order of elements reported back via | 
|  | // ChromeSearchboxStats is irrelevant. flat_set uses std::vector as a | 
|  | // container, reducing memory overhead of keeping a handful of integers, while | 
|  | // offering similar functionality as std::set. | 
|  | // | 
|  | // This set may contain int values not present in omnibox::SuggestSubtype | 
|  | // enum. This is because the list of subtypes in omnibox::SuggestSubtype enum | 
|  | // is not exhaustive. However, casting int values into omnibox::SuggestSubtype | 
|  | // enum without testing membership is expected to be safe as | 
|  | // omnibox::SuggestSubtype enum has a fixed int underlying type. | 
|  | base::flat_set<omnibox::SuggestSubtype> subtypes; | 
|  |  | 
|  | // True if we saw a tab that matched this suggestion. | 
|  | // Unset if it has not been computed yet. | 
|  | std::optional<bool> has_tab_match; | 
|  |  | 
|  | // Set to a `TemplateURL`'s keyword; e.g. 'youtube.com' or '@bookmarks'. Set | 
|  | // by the `AutocompleteController`, not individual providers. This determines | 
|  | // which keyword to activate if the user focuses this instant-keyword (e.g. | 
|  | // '@bookmarks') or this match's keyword chip (e.g. 'youtube.com'). | 
|  | std::u16string associated_keyword; | 
|  |  | 
|  | // The keyword of the TemplateURL the match originated from.  This is nonempty | 
|  | // for both explicit "keyword mode" matches as well as matches for the default | 
|  | // search provider (so, any match for which we're doing substitution); it | 
|  | // doesn't imply (alone) that the UI is going to show a keyword hint or | 
|  | // keyword mode.  For that, see GetKeywordUIState() or | 
|  | // GetSubstitutingExplicitlyInvokedKeyword(). | 
|  | // | 
|  | // CAUTION: The TemplateURL associated with this keyword may be deleted or | 
|  | // modified while the AutocompleteMatch is alive.  This means anyone who | 
|  | // accesses it must perform any necessary sanity checks before blindly using | 
|  | // it! | 
|  | std::u16string keyword; | 
|  |  | 
|  | // Set in matches originating in keyword mode. `from_keyword` can be true even | 
|  | // if `keyword` is empty and vice versa. `from_keyword` basically means the | 
|  | // user input is in keyword mode. `!keyword.empty()` basically means the match | 
|  | // was generated using a template URL. | 
|  | // | 
|  | // CAUTION: Not consistently set by all providers. That's fine-ish since this | 
|  | // field isn't used much. But code relying on this feature to be correctly set | 
|  | // should take care. | 
|  | bool from_keyword = false; | 
|  |  | 
|  | // The visible actions relevant to this match. | 
|  | std::vector<scoped_refptr<OmniboxAction>> actions; | 
|  |  | 
|  | // An optional invisible action that takes over the match navigation. That is: | 
|  | // if provided, when the user selects the match, the navigation is ignored and | 
|  | // this action is executed instead. | 
|  | scoped_refptr<OmniboxAction> takeover_action; | 
|  |  | 
|  | // True if this match is from a previous result. | 
|  | bool from_previous = false; | 
|  |  | 
|  | // Session-based metrics struct that tracks various bits of info during the | 
|  | // course of a single Omnibox session (e.g. number of ZPS shown, etc.). | 
|  | std::optional<SessionData> session; | 
|  |  | 
|  | // Optional search terms args.  If present, | 
|  | // AutocompleteController::UpdateSearchboxStats() will incorporate this data | 
|  | // with additional data it calculates and pass the completed struct to | 
|  | // TemplateURLRef::ReplaceSearchTerms() to reset the match's |destination_url| | 
|  | // after the complete set of matches in the AutocompleteResult has been chosen | 
|  | // and sorted.  Most providers will leave this as NULL, which will cause the | 
|  | // AutocompleteController to do no additional transformations. | 
|  | std::unique_ptr<TemplateURLRef::SearchTermsArgs> search_terms_args; | 
|  |  | 
|  | // Optional post content. If this is set, the request to load the destination | 
|  | // url will pass this post content as well. | 
|  | std::unique_ptr<TemplateURLRef::PostContent> post_content; | 
|  |  | 
|  | // Information dictionary into which each provider can optionally record a | 
|  | // property and associated value and which is presented in chrome://omnibox. | 
|  | AdditionalInfo additional_info; | 
|  |  | 
|  | // A vector of matches culled during de-duplication process, sorted from | 
|  | // second-best to worst according to the de-duplication preference criteria. | 
|  | // This vector is retained so that if the user deletes a match, all the | 
|  | // duplicates are deleted as well. This is also used for re-duping Search | 
|  | // Entity vs. plain Search suggestions. | 
|  | std::vector<AutocompleteMatch> duplicate_matches; | 
|  |  | 
|  | // A list of navsuggest tiles to be shown as part of this match. | 
|  | // This object is only populated for TILE_NAVSUGGEST AutocompleteMatches. | 
|  | std::vector<SuggestTile> suggest_tiles; | 
|  |  | 
|  | // Signals for ML scoring. | 
|  | std::optional<ScoringSignals> scoring_signals; | 
|  |  | 
|  | // A flag to mark whether this would've been excluded from the "original" list | 
|  | // of matches. Traditionally, providers limit the number of suggestions they | 
|  | // provide to the top N most relevant matches. When ML scoring is enabled, | 
|  | // however, providers pass ALL suggestion candidates to the controller. When | 
|  | // this flag is true, this match is an "extra" suggestion that would've | 
|  | // originally been culled by the provider. | 
|  | // TODO(yoangela|manukh): Currently unused except in tests. Remove if not | 
|  | //   needed. Might be needed when increasing the max provider limit? | 
|  | bool culled_by_provider = false; | 
|  |  | 
|  | // True for shortcut suggestions that were boosted. Used for grouping logic. | 
|  | // TODO(manukh): Remove this field and use `suggestion_group_id` once grouping | 
|  | //   launches. In the meantime, shortcut grouping won't work for users in the | 
|  | //   grouping experiments. | 
|  | bool shortcut_boosted = false; | 
|  |  | 
|  | // E.g. the gemini IPH match shown at the bottom of the popup. | 
|  | IphType iph_type = IphType::kNone; | 
|  |  | 
|  | // IPH matches aren't clickable like other matches, but may have a next-action | 
|  | // or learn-more type of link. This link is always appended to the end of | 
|  | // their contents/description text. | 
|  | std::u16string iph_link_text; | 
|  | GURL iph_link_url; | 
|  |  | 
|  | // The text to show above the match contents & description for | 
|  | // `HISTORY_EMBEDDINGS_ANSWER` matches. | 
|  | std::u16string history_embeddings_answer_header_text; | 
|  | // Whether the answer is still loading and should therefore show a throbber. | 
|  | bool history_embeddings_answer_header_loading = false; | 
|  |  | 
|  | // The user feedback on the match. | 
|  | FeedbackType feedback_type = FeedbackType::kNone; | 
|  |  | 
|  | // Stores the matching tab group uuid for this suggestion. | 
|  | std::optional<base::Uuid> matching_tab_group_uuid = std::nullopt; | 
|  |  | 
|  | // So users of AutocompleteMatch can use the same ellipsis that it uses. | 
|  | static const char16_t kEllipsis[]; | 
|  |  | 
|  | #if DCHECK_IS_ON() | 
|  | // Does a data integrity check on this match. | 
|  | void Validate() const; | 
|  | #endif  // DCHECK_IS_ON() | 
|  |  | 
|  | // Checks one text/classifications pair for valid values. | 
|  | static void ValidateClassifications( | 
|  | const std::u16string& text, | 
|  | const ACMatchClassifications& classifications, | 
|  | const std::string& provider_name = ""); | 
|  |  | 
|  | private: | 
|  | #if BUILDFLAG(IS_ANDROID) | 
|  | // Corresponding Java object. | 
|  | // This element should not be copied with the rest of the AutocompleteMatch | 
|  | // object to ensure consistent 1:1 relationship between the objects. | 
|  | // This object should never be accessed directly. To acquire a reference to | 
|  | // java object, call the GetOrCreateJavaObject(). | 
|  | // Note that this object is lazily constructed to avoid creating Java matches | 
|  | // for throw away AutocompleteMatch objects, eg. during Classify() or | 
|  | // QualifyPartialUrlQuery() calls. | 
|  | // See AutocompleteControllerAndroid for more details. | 
|  | mutable std::unique_ptr<base::android::ScopedJavaGlobalRef<jobject>> | 
|  | java_match_; | 
|  |  | 
|  | base::WeakPtrFactory<AutocompleteMatch> weak_ptr_factory_{this}; | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | typedef AutocompleteMatch::ACMatchClassification ACMatchClassification; | 
|  | typedef std::vector<ACMatchClassification> ACMatchClassifications; | 
|  | typedef std::vector<AutocompleteMatch> ACMatches; | 
|  |  | 
|  | // Can be used as the key for grouping AutocompleteMatches in a map based on a | 
|  | // std::tuple of fields. | 
|  | // The accompanying hash function makes the key usable in an std::unordered_map. | 
|  | template <typename... Args> | 
|  | using ACMatchKey = std::tuple<Args...>; | 
|  |  | 
|  | template <typename... Args> | 
|  | struct ACMatchKeyHash { | 
|  | size_t operator()(const ACMatchKey<Args...>& key) const; | 
|  | }; | 
|  |  | 
|  | #endif  // COMPONENTS_OMNIBOX_BROWSER_AUTOCOMPLETE_MATCH_H_ |