1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_H_ 7 8 #include <set> 9 #include <string> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/scoped_observer.h" 13 #include "base/strings/string16.h" 14 #include "chrome/browser/autocomplete/autocomplete_match.h" 15 #include "chrome/browser/extensions/chrome_extension_function.h" 16 #include "chrome/browser/extensions/extension_icon_manager.h" 17 #include "chrome/browser/search_engines/template_url_service.h" 18 #include "chrome/common/extensions/api/omnibox.h" 19 #include "extensions/browser/browser_context_keyed_api_factory.h" 20 #include "extensions/browser/extension_registry_observer.h" 21 #include "ui/base/window_open_disposition.h" 22 23 class Profile; 24 class TemplateURL; 25 class TemplateURLService; 26 27 namespace base { 28 class ListValue; 29 } 30 31 namespace content { 32 class BrowserContext; 33 class WebContents; 34 } 35 36 namespace gfx { 37 class Image; 38 } 39 40 namespace extensions { 41 class ExtensionRegistry; 42 43 // Event router class for events related to the omnibox API. 44 class ExtensionOmniboxEventRouter { 45 public: 46 // The user has just typed the omnibox keyword. This is sent exactly once in 47 // a given input session, before any OnInputChanged events. 48 static void OnInputStarted( 49 Profile* profile, const std::string& extension_id); 50 51 // The user has changed what is typed into the omnibox while in an extension 52 // keyword session. Returns true if someone is listening to this event, and 53 // thus we have some degree of confidence we'll get a response. 54 static bool OnInputChanged( 55 Profile* profile, 56 const std::string& extension_id, 57 const std::string& input, int suggest_id); 58 59 // The user has accepted the omnibox input. 60 static void OnInputEntered( 61 content::WebContents* web_contents, 62 const std::string& extension_id, 63 const std::string& input, 64 WindowOpenDisposition disposition); 65 66 // The user has cleared the keyword, or closed the omnibox popup. This is 67 // sent at most once in a give input session, after any OnInputChanged events. 68 static void OnInputCancelled( 69 Profile* profile, const std::string& extension_id); 70 71 private: 72 DISALLOW_COPY_AND_ASSIGN(ExtensionOmniboxEventRouter); 73 }; 74 75 class OmniboxSendSuggestionsFunction : public ChromeSyncExtensionFunction { 76 public: 77 DECLARE_EXTENSION_FUNCTION("omnibox.sendSuggestions", OMNIBOX_SENDSUGGESTIONS) 78 79 protected: ~OmniboxSendSuggestionsFunction()80 virtual ~OmniboxSendSuggestionsFunction() {} 81 82 // ExtensionFunction: 83 virtual bool RunSync() OVERRIDE; 84 }; 85 86 class OmniboxAPI : public BrowserContextKeyedAPI, 87 public ExtensionRegistryObserver { 88 public: 89 explicit OmniboxAPI(content::BrowserContext* context); 90 virtual ~OmniboxAPI(); 91 92 // BrowserContextKeyedAPI implementation. 93 static BrowserContextKeyedAPIFactory<OmniboxAPI>* GetFactoryInstance(); 94 95 // Convenience method to get the OmniboxAPI for a profile. 96 static OmniboxAPI* Get(content::BrowserContext* context); 97 98 // KeyedService implementation. 99 virtual void Shutdown() OVERRIDE; 100 101 // Returns the icon to display in the omnibox for the given extension. 102 gfx::Image GetOmniboxIcon(const std::string& extension_id); 103 104 // Returns the icon to display in the omnibox popup window for the given 105 // extension. 106 gfx::Image GetOmniboxPopupIcon(const std::string& extension_id); 107 108 private: 109 friend class BrowserContextKeyedAPIFactory<OmniboxAPI>; 110 111 typedef std::set<const Extension*> PendingExtensions; 112 113 void OnTemplateURLsLoaded(); 114 115 // ExtensionRegistryObserver implementation. 116 virtual void OnExtensionLoaded(content::BrowserContext* browser_context, 117 const Extension* extension) OVERRIDE; 118 virtual void OnExtensionUnloaded( 119 content::BrowserContext* browser_context, 120 const Extension* extension, 121 UnloadedExtensionInfo::Reason reason) OVERRIDE; 122 123 // BrowserContextKeyedAPI implementation. service_name()124 static const char* service_name() { 125 return "OmniboxAPI"; 126 } 127 static const bool kServiceRedirectedInIncognito = true; 128 129 Profile* profile_; 130 131 TemplateURLService* url_service_; 132 133 // List of extensions waiting for the TemplateURLService to Load to 134 // have keywords registered. 135 PendingExtensions pending_extensions_; 136 137 // Listen to extension load, unloaded notifications. 138 ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 139 extension_registry_observer_; 140 141 // Keeps track of favicon-sized omnibox icons for extensions. 142 ExtensionIconManager omnibox_icon_manager_; 143 ExtensionIconManager omnibox_popup_icon_manager_; 144 145 scoped_ptr<TemplateURLService::Subscription> template_url_sub_; 146 147 DISALLOW_COPY_AND_ASSIGN(OmniboxAPI); 148 }; 149 150 template <> 151 void BrowserContextKeyedAPIFactory<OmniboxAPI>::DeclareFactoryDependencies(); 152 153 class OmniboxSetDefaultSuggestionFunction : public ChromeSyncExtensionFunction { 154 public: 155 DECLARE_EXTENSION_FUNCTION("omnibox.setDefaultSuggestion", 156 OMNIBOX_SETDEFAULTSUGGESTION) 157 158 protected: ~OmniboxSetDefaultSuggestionFunction()159 virtual ~OmniboxSetDefaultSuggestionFunction() {} 160 161 // ExtensionFunction: 162 virtual bool RunSync() OVERRIDE; 163 }; 164 165 // If the extension has set a custom default suggestion via 166 // omnibox.setDefaultSuggestion, apply that to |match|. Otherwise, do nothing. 167 void ApplyDefaultSuggestionForExtensionKeyword( 168 Profile* profile, 169 const TemplateURL* keyword, 170 const base::string16& remaining_input, 171 AutocompleteMatch* match); 172 173 // This function converts style information populated by the JSON schema 174 // // compiler into an ACMatchClassifications object. 175 ACMatchClassifications StyleTypesToACMatchClassifications( 176 const api::omnibox::SuggestResult &suggestion); 177 178 } // namespace extensions 179 180 #endif // CHROME_BROWSER_EXTENSIONS_API_OMNIBOX_OMNIBOX_API_H_ 181