File: omnibox_api.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (231 lines) | stat: -rw-r--r-- 8,590 bytes parent folder | download | duplicates (4)
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
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_H_

#include <set>
#include <string>

#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/extensions/api/omnibox/suggestion_parser.h"
#include "chrome/common/extensions/api/omnibox.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/extension_suggestion.h"
#include "components/search_engines/template_url_service.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_icon_manager.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_registry_observer.h"
#include "extensions/browser/permissions_manager.h"
#include "extensions/common/extension_id.h"
#include "ui/base/window_open_disposition.h"

class Profile;
class TemplateURL;
class TemplateURLService;

namespace content {
class BrowserContext;
class WebContents;
}

namespace gfx {
class Image;
}

namespace extensions {

// Event router class for events related to the omnibox API.
class ExtensionOmniboxEventRouter {
 public:
  static constexpr size_t kMaxSuggestionActions = 7;
  static constexpr char kMaxSuggestionActionsExceededError[] =
      "Found suggest result with %d action, which exceeds the limit of %d "
      "actions per suggestion.";
  static constexpr char kActionsRequireDirectInputPermissionError[] =
      "Actions in suggest results require omnibox.directInput permission.";
  static constexpr char kActionIconError[] =
      "Action icon failed to parse for suggestion description: %s and action "
      "name: %s.";

  ExtensionOmniboxEventRouter(const ExtensionOmniboxEventRouter&) = delete;
  ExtensionOmniboxEventRouter& operator=(const ExtensionOmniboxEventRouter&) =
      delete;

  // The user has just typed the omnibox keyword. This is sent exactly once in
  // a given input session, before any OnInputChanged events.
  static void OnInputStarted(Profile* profile, const ExtensionId& extension_id);

  // The user has changed what is typed into the omnibox while in an extension
  // keyword session. Returns true if someone is listening to this event, and
  // thus we have some degree of confidence we'll get a response.
  static bool OnInputChanged(Profile* profile,
                             const ExtensionId& extension_id,
                             const std::string& input,
                             int suggest_id);

  // The user has accepted the omnibox input.
  static void OnInputEntered(content::WebContents* web_contents,
                             const ExtensionId& extension_id,
                             const std::string& input,
                             WindowOpenDisposition disposition);

  // The user has cleared the keyword, or closed the omnibox popup. This is
  // sent at most once in a give input session, after any OnInputChanged events.
  static void OnInputCancelled(Profile* profile,
                               const ExtensionId& extension_id);

  // The user has deleted an extension omnibox suggestion result.
  static void OnDeleteSuggestion(Profile* profile,
                                 const ExtensionId& extension_id,
                                 const std::string& suggestion_text);

  // The user has clicked an action of an extension omnibox suggestion result.
  static void OnActionExecuted(Profile* profile,
                               const ExtensionId& extension_id,
                               const std::string& action_name,
                               const std::string& content);
};

class OmniboxSendSuggestionsFunction : public ExtensionFunction {
 public:
  OmniboxSendSuggestionsFunction();

  DECLARE_EXTENSION_FUNCTION("omnibox.sendSuggestions", OMNIBOX_SENDSUGGESTIONS)

 protected:
  ~OmniboxSendSuggestionsFunction() override;

  // ExtensionFunction:
  ResponseAction Run() override;

 private:
  // Called with the result of parsing the omnibox suggestions.
  void OnParsedDescriptionsAndStyles(DescriptionAndStylesResult result);

  // Notifies the omnibox that the suggestions have been prepared.
  void NotifySuggestionsReady();

  // The parsed `params_.suggest_results`.
  std::vector<ExtensionSuggestion> extension_suggestions_;

  int request_id_;
};

class OmniboxAPI : public BrowserContextKeyedAPI,
                   public ExtensionRegistryObserver,
                   public PermissionsManager::Observer {
 public:
  explicit OmniboxAPI(content::BrowserContext* context);

  OmniboxAPI(const OmniboxAPI&) = delete;
  OmniboxAPI& operator=(const OmniboxAPI&) = delete;

  ~OmniboxAPI() override;

  // BrowserContextKeyedAPI implementation.
  static BrowserContextKeyedAPIFactory<OmniboxAPI>* GetFactoryInstance();

  // Convenience method to get the OmniboxAPI for a profile.
  static OmniboxAPI* Get(content::BrowserContext* context);

  // KeyedService implementation.
  void Shutdown() override;

  // Returns the icon to display in the location bar or omnibox popup for the
  // given extension.
  gfx::Image GetOmniboxIcon(const ExtensionId& extension_id);

 private:
  friend class BrowserContextKeyedAPIFactory<OmniboxAPI>;

  typedef std::set<raw_ptr<const Extension, SetExperimental>> PendingExtensions;

  void OnTemplateURLsLoaded();

  // ExtensionRegistryObserver implementation.
  void OnExtensionLoaded(content::BrowserContext* browser_context,
                         const Extension* extension) override;
  void OnExtensionUnloaded(content::BrowserContext* browser_context,
                           const Extension* extension,
                           UnloadedExtensionReason reason) override;

  // PermissionsManager::Observer:
  void OnExtensionPermissionsUpdated(
      const Extension& extension,
      const PermissionSet& permissions,
      PermissionsManager::UpdateReason reason) override;

  // BrowserContextKeyedAPI implementation.
  static const char* service_name() {
    return "OmniboxAPI";
  }
  static const bool kServiceRedirectedInIncognito = true;

  raw_ptr<Profile> profile_;

  raw_ptr<TemplateURLService> url_service_;

  // List of extensions waiting for the TemplateURLService to Load to
  // have keywords registered.
  PendingExtensions pending_extensions_;

  // Listen to extension load, unloaded notifications.
  base::ScopedObservation<ExtensionRegistry, ExtensionRegistryObserver>
      extension_registry_observation_{this};

  // Permissions observer to listen to `omnibox.directInput` permission changes.
  base::ScopedObservation<extensions::PermissionsManager,
                          extensions::PermissionsManager::Observer>
      permissions_manager_observation_{this};

  // Keeps track of favicon-sized omnibox icons for extensions.
  ExtensionIconManager omnibox_icon_manager_;

  base::CallbackListSubscription template_url_subscription_;
};

template <>
void BrowserContextKeyedAPIFactory<OmniboxAPI>::DeclareFactoryDependencies();

class OmniboxSetDefaultSuggestionFunction : public ExtensionFunction {
 public:
  DECLARE_EXTENSION_FUNCTION("omnibox.setDefaultSuggestion",
                             OMNIBOX_SETDEFAULTSUGGESTION)

 protected:
  ~OmniboxSetDefaultSuggestionFunction() override = default;

  // Called asynchronously with the parsed description and styles for the
  // default suggestion.
  void OnParsedDescriptionAndStyles(DescriptionAndStylesResult result);

  // Sets the default suggestion in the extension preferences.
  void SetDefaultSuggestion(
      const api::omnibox::DefaultSuggestResult& suggestion);

  // ExtensionFunction:
  ResponseAction Run() override;
};

// If the extension has set a custom default suggestion via
// omnibox.setDefaultSuggestion, apply that to `match`. Otherwise, do nothing.
void ApplyDefaultSuggestionForExtensionKeyword(
    Profile* profile,
    const TemplateURL* keyword,
    const std::u16string& remaining_input,
    AutocompleteMatch* match);

// This function converts style information populated by the JSON schema
// // compiler into an ACMatchClassifications object.
ACMatchClassifications StyleTypesToACMatchClassifications(
    const std::vector<api::omnibox::MatchClassification>* description_styles,
    const std::string& suggestion_description);

}  // namespace extensions

#endif  // CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_H_