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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
|
// 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,
};
// 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"
};
// clang-format on
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;
// Contains a bitmask of flags defined in enum Style.
int style;
};
// 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 UpdateJavaDestinationUrl();
// Update the Java object with new Answer-in-Suggest.
void UpdateJavaAnswer();
// Update the Java object description.
void UpdateJavaDescription();
// Update the pointer to corresponding Java tab object.
void UpdateMatchingJavaTab(const JavaObjectWeakGlobalRef& tab);
// Get the matching Java Tab object.
JavaObjectWeakGlobalRef GetMatchingJavaTab() const;
#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;
// 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(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 NULL if
// the match has no keyword OR if the keyword no longer corresponds to a valid
// TemplateURL. See comments on |keyword| below.
// If |allow_fallback_to_destination_host| is true and the keyword does
// not map to a valid TemplateURL, we'll then check for a TemplateURL that
// corresponds to the destination_url's hostname.
TemplateURL* GetTemplateURL(TemplateURLService* template_url_service,
bool allow_fallback_to_destination_host) 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. See `NavigateParams::extra_headers`
// for how headers should be represented.
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 with a keyword provider match if this match can show a keyword hint.
// For example, if this is a SearchProvider match for "www.amazon.com",
// |associated_keyword| could be a KeywordProvider match for "amazon.com".
//
// When this is set, the popup will show a ">" symbol at the right edge of the
// line for this match, and tab/shift-tab will toggle in and out of keyword
// mode without disturbing the rest of the popup. See also
// OmniboxPopupModel::SetSelectedLineState().
std::unique_ptr<AutocompleteMatch> 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_;
// When set, holds a weak reference to Java Tab object.
JavaObjectWeakGlobalRef matching_java_tab_{};
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_
|