protocol_handler_registry.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ 6#define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ 7 8#include <map> 9#include <string> 10#include <vector> 11 12#include "base/basictypes.h" 13#include "base/memory/ref_counted.h" 14#include "base/sequenced_task_runner_helpers.h" 15#include "base/values.h" 16#include "chrome/browser/profiles/profile.h" 17#include "chrome/browser/shell_integration.h" 18#include "chrome/common/custom_handlers/protocol_handler.h" 19#include "content/public/browser/browser_thread.h" 20#include "content/public/browser/notification_service.h" 21#include "net/url_request/url_request.h" 22#include "net/url_request/url_request_job.h" 23#include "net/url_request/url_request_job_factory.h" 24 25// This is where handlers for protocols registered with 26// navigator.registerProtocolHandler() are registered. Each Profile owns an 27// instance of this class, which is initialized on browser start through 28// Profile::InitRegisteredProtocolHandlers(), and they should be the only 29// instances of this class. 30class ProtocolHandlerRegistry : public ProfileKeyedService { 31 32 public: 33 // Provides notification of when the OS level user agent settings 34 // are changed. 35 class DefaultClientObserver 36 : public ShellIntegration::DefaultWebClientObserver { 37 public: 38 explicit DefaultClientObserver(ProtocolHandlerRegistry* registry); 39 virtual ~DefaultClientObserver(); 40 41 // Get response from the worker regarding whether Chrome is the default 42 // handler for the protocol. 43 virtual void SetDefaultWebClientUIState( 44 ShellIntegration::DefaultWebClientUIState state) OVERRIDE; 45 46 virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE; 47 48 // Give the observer a handle to the worker, so we can find out the protocol 49 // when we're called and also tell the worker if we get deleted. 50 void SetWorker(ShellIntegration::DefaultProtocolClientWorker* worker); 51 52 protected: 53 ShellIntegration::DefaultProtocolClientWorker* worker_; 54 55 private: 56 virtual bool IsOwnedByWorker() OVERRIDE; 57 58 // This is a raw pointer, not reference counted, intentionally. In general 59 // subclasses of DefaultWebClientObserver are not able to be refcounted 60 // e.g. the browser options page 61 ProtocolHandlerRegistry* registry_; 62 63 DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver); 64 }; 65 66 // |Delegate| provides an interface for interacting asynchronously 67 // with the underlying OS for the purposes of registering Chrome 68 // as the default handler for specific protocols. 69 class Delegate { 70 public: 71 virtual ~Delegate(); 72 virtual void RegisterExternalHandler(const std::string& protocol); 73 virtual void DeregisterExternalHandler(const std::string& protocol); 74 virtual bool IsExternalHandlerRegistered(const std::string& protocol); 75 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( 76 ShellIntegration::DefaultWebClientObserver* observer, 77 const std::string& protocol); 78 virtual DefaultClientObserver* CreateShellObserver( 79 ProtocolHandlerRegistry* registry); 80 virtual void RegisterWithOSAsDefaultClient( 81 const std::string& protocol, 82 ProtocolHandlerRegistry* registry); 83 }; 84 85 typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap; 86 typedef std::vector<ProtocolHandler> ProtocolHandlerList; 87 typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap; 88 typedef std::vector<DefaultClientObserver*> DefaultClientObserverList; 89 90 // Creates a new instance. Assumes ownership of |delegate|. 91 ProtocolHandlerRegistry(Profile* profile, Delegate* delegate); 92 virtual ~ProtocolHandlerRegistry(); 93 94 // Returns a net::URLRequestJobFactory::Interceptor suitable 95 // for use on the IO thread, but is initialized on the UI thread. 96 // Callers assume responsibility for deleting this object. 97 net::URLRequestJobFactory::Interceptor* CreateURLInterceptor(); 98 99 // Called when a site tries to register as a protocol handler. If the request 100 // can be handled silently by the registry - either to ignore the request 101 // or to update an existing handler - the request will succeed. If this 102 // function returns false the user needs to be prompted for confirmation. 103 bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler); 104 105 // Called when the user accepts the registration of a given protocol handler. 106 void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler); 107 108 // Called when the user denies the registration of a given protocol handler. 109 void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler); 110 111 // Called when the user indicates that they don't want to be asked about the 112 // given protocol handler again. 113 void OnIgnoreRegisterProtocolHandler(const ProtocolHandler& handler); 114 115 // Removes all handlers that have the same origin and protocol as the given 116 // one and installs the given handler. Returns true if any protocol handlers 117 // were replaced. 118 bool AttemptReplace(const ProtocolHandler& handler); 119 120 // Returns a list of protocol handlers that can be replaced by the given 121 // handler. 122 ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const; 123 124 // Clears the default for the provided protocol. 125 void ClearDefault(const std::string& scheme); 126 127 // Returns true if this handler is the default handler for its protocol. 128 bool IsDefault(const ProtocolHandler& handler) const; 129 130 // Initializes default protocol settings and loads them from prefs. 131 // This method must be called to complete initialization of the 132 // registry after creation, and prior to use. 133 void InitProtocolSettings(); 134 135 // Returns the offset in the list of handlers for a protocol of the default 136 // handler for that protocol. 137 int GetHandlerIndex(const std::string& scheme) const; 138 139 // Get the list of protocol handlers for the given scheme. 140 ProtocolHandlerList GetHandlersFor(const std::string& scheme) const; 141 142 // Get the list of ignored protocol handlers. 143 ProtocolHandlerList GetIgnoredHandlers(); 144 145 // Yields a list of the protocols that have handlers registered in this 146 // registry. 147 void GetRegisteredProtocols(std::vector<std::string>* output) const; 148 149 // Returns true if we allow websites to register handlers for the given 150 // scheme. 151 bool CanSchemeBeOverridden(const std::string& scheme) const; 152 153 // Returns true if an identical protocol handler has already been registered. 154 bool IsRegistered(const ProtocolHandler& handler) const; 155 156 // Returns true if an identical protocol handler is being ignored. 157 bool IsIgnored(const ProtocolHandler& handler) const; 158 159 // Returns true if an equivalent protocol handler has already been registered. 160 bool HasRegisteredEquivalent(const ProtocolHandler& handler) const; 161 162 // Returns true if an equivalent protocol handler is being ignored. 163 bool HasIgnoredEquivalent(const ProtocolHandler& handler) const; 164 165 // Causes the given protocol handler to not be ignored anymore. 166 void RemoveIgnoredHandler(const ProtocolHandler& handler); 167 168 // Returns true if the protocol has a default protocol handler. 169 bool IsHandledProtocol(const std::string& scheme) const; 170 171 // Removes the given protocol handler from the registry. 172 void RemoveHandler(const ProtocolHandler& handler); 173 174 // Remove the default handler for the given protocol. 175 void RemoveDefaultHandler(const std::string& scheme); 176 177 // Returns the default handler for this protocol, or an empty handler if none 178 // exists. 179 const ProtocolHandler& GetHandlerFor(const std::string& scheme) const; 180 181 // Puts this registry in the enabled state - registered protocol handlers 182 // will handle requests. 183 void Enable(); 184 185 // Puts this registry in the disabled state - registered protocol handlers 186 // will not handle requests. 187 void Disable(); 188 189 // This is called by the UI thread when the system is shutting down. This 190 // does finalization which must be done on the UI thread. 191 virtual void Shutdown() OVERRIDE; 192 193 // Registers the preferences that we store registered protocol handlers in. 194 static void RegisterPrefs(PrefService* prefService); 195 196 bool enabled() const { return enabled_; } 197 198 // Add a predefined protocol handler. This has to be called before the first 199 // load command was issued, otherwise the command will be ignored. 200 void AddPredefinedHandler(const ProtocolHandler& handler); 201 202 private: 203 friend class base::DeleteHelper<ProtocolHandlerRegistry>; 204 friend struct content::BrowserThread::DeleteOnThread< 205 content::BrowserThread::IO>; 206 207 // for access to InstallDefaultsForChromeOS 208 friend class ProtocolHandlerRegistryFactory; 209 210 friend class ProtocolHandlerRegistryTest; 211 friend class RegisterProtocolHandlerBrowserTest; 212 213 // Forward declaration of the internal implementation classes. 214 class Core; 215 class URLInterceptor; 216 217 // Puts the given handler at the top of the list of handlers for its 218 // protocol. 219 void PromoteHandler(const ProtocolHandler& handler); 220 221 // Saves a user's registered protocol handlers. 222 void Save(); 223 224 // Returns a pointer to the list of handlers registered for the given scheme, 225 // or NULL if there are none. 226 const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const; 227 228 // Install default protocol handlers for chromeos which must be done 229 // prior to calling InitProtocolSettings. 230 void InstallDefaultsForChromeOS(); 231 232 // Makes this ProtocolHandler the default handler for its protocol. 233 void SetDefault(const ProtocolHandler& handler); 234 235 // Insert the given ProtocolHandler into the registry. 236 void InsertHandler(const ProtocolHandler& handler); 237 238 // Returns a JSON list of protocol handlers. The caller is responsible for 239 // deleting this Value. 240 Value* EncodeRegisteredHandlers(); 241 242 // Returns a JSON list of ignored protocol handlers. The caller is 243 // responsible for deleting this Value. 244 Value* EncodeIgnoredHandlers(); 245 246 // Sends a notification of the given type to the NotificationService. 247 void NotifyChanged(); 248 249 // Registers a new protocol handler. 250 void RegisterProtocolHandler(const ProtocolHandler& handler); 251 252 // Get the DictionaryValues stored under the given pref name that are valid 253 // ProtocolHandler values. 254 std::vector<const DictionaryValue*> GetHandlersFromPref( 255 const char* pref_name) const; 256 257 // Ignores future requests to register the given protocol handler. 258 void IgnoreProtocolHandler(const ProtocolHandler& handler); 259 260 // Map from protocols (strings) to protocol handlers. 261 ProtocolHandlerMultiMap protocol_handlers_; 262 263 // Protocol handlers that the user has told us to ignore. 264 ProtocolHandlerList ignored_protocol_handlers_; 265 266 // Protocol handlers that are the defaults for a given protocol. 267 ProtocolHandlerMap default_handlers_; 268 269 // The Profile that owns this ProtocolHandlerRegistry. 270 Profile* profile_; 271 272 // The Delegate that registers / deregisters external handlers on our behalf. 273 scoped_ptr<Delegate> delegate_; 274 275 // If false then registered protocol handlers will not be used to handle 276 // requests. 277 bool enabled_; 278 279 // Whether or not we are loading. 280 bool is_loading_; 281 282 // When the table gets loaded this flag will be set and any further calls to 283 // AddPredefinedHandler will be rejected. 284 bool is_loaded_; 285 286 // Copy of registry data for use on the IO thread. Changes to the registry 287 // are posted to the IO thread where updates are applied to this object. 288 scoped_refptr<Core> core_; 289 290 DefaultClientObserverList default_client_observers_; 291 292 DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry); 293}; 294#endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ 295