Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ | 5 #ifndef CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ | 
| 6 #define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ | 6 #define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ | 
| 7 | 7 | 
| 8 #include <map> | 8 #include <map> | 
| 9 #include <string> | 9 #include <string> | 
| 10 #include <vector> | 10 #include <vector> | 
| 11 | 11 | 
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" | 
| 13 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" | 
| 14 #include "base/sequenced_task_runner_helpers.h" | 14 #include "base/sequenced_task_runner_helpers.h" | 
| 15 #include "base/values.h" | 15 #include "base/values.h" | 
| 16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" | 
| 17 #include "chrome/browser/shell_integration.h" | 17 #include "chrome/browser/shell_integration.h" | 
| 18 #include "chrome/common/custom_handlers/protocol_handler.h" | 18 #include "chrome/common/custom_handlers/protocol_handler.h" | 
| 19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" | 
| 20 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" | 
| 21 #include "net/url_request/url_request.h" | 21 #include "net/url_request/url_request.h" | 
| 22 #include "net/url_request/url_request_job.h" | 22 #include "net/url_request/url_request_job.h" | 
| 23 #include "net/url_request/url_request_job_factory.h" | |
| 23 | 24 | 
| 24 // This is where handlers for protocols registered with | 25 // This is where handlers for protocols registered with | 
| 25 // navigator.registerProtocolHandler() are registered. Each Profile owns an | 26 // navigator.registerProtocolHandler() are registered. Each Profile owns an | 
| 26 // instance of this class, which is initialized on browser start through | 27 // instance of this class, which is initialized on browser start through | 
| 27 // Profile::InitRegisteredProtocolHandlers(), and they should be the only | 28 // Profile::InitRegisteredProtocolHandlers(), and they should be the only | 
| 28 // instances of this class. | 29 // instances of this class. | 
| 30 class ProtocolHandlerRegistry : public ProfileKeyedService { | |
| 29 | 31 | 
| 30 class ProtocolHandlerRegistry | |
| 31 : public base::RefCountedThreadSafe< | |
| 32 ProtocolHandlerRegistry, content::BrowserThread::DeleteOnIOThread> { | |
| 33 public: | 32 public: | 
| 33 // Provides notification of when the OS level user agent settings | |
| 34 // are changed. | |
| 34 class DefaultClientObserver | 35 class DefaultClientObserver | 
| 35 : public ShellIntegration::DefaultWebClientObserver { | 36 : public ShellIntegration::DefaultWebClientObserver { | 
| 36 public: | 37 public: | 
| 37 explicit DefaultClientObserver(ProtocolHandlerRegistry* registry); | 38 explicit DefaultClientObserver(ProtocolHandlerRegistry* registry); | 
| 38 virtual ~DefaultClientObserver(); | 39 virtual ~DefaultClientObserver(); | 
| 39 | 40 | 
| 40 // Get response from the worker regarding whether Chrome is the default | 41 // Get response from the worker regarding whether Chrome is the default | 
| 41 // handler for the protocol. | 42 // handler for the protocol. | 
| 42 virtual void SetDefaultWebClientUIState( | 43 virtual void SetDefaultWebClientUIState( | 
| 43 ShellIntegration::DefaultWebClientUIState state) OVERRIDE; | 44 ShellIntegration::DefaultWebClientUIState state) OVERRIDE; | 
| 44 | 45 | 
| 45 // Give the observer a handle to the worker, so we can find out the protocol | 46 // Give the observer a handle to the worker, so we can find out the protocol | 
| 46 // when we're called and also tell the worker if we get deleted. | 47 // when we're called and also tell the worker if we get deleted. | 
| 47 void SetWorker(ShellIntegration::DefaultProtocolClientWorker* worker); | 48 void SetWorker(ShellIntegration::DefaultProtocolClientWorker* worker); | 
| 48 | 49 | 
| 49 protected: | 50 protected: | 
| 50 ShellIntegration::DefaultProtocolClientWorker* worker_; | 51 ShellIntegration::DefaultProtocolClientWorker* worker_; | 
| 51 | 52 | 
| 52 private: | 53 private: | 
| 53 virtual bool IsOwnedByWorker() OVERRIDE { return true; } | 54 virtual bool IsOwnedByWorker() OVERRIDE { return true; } | 
| 54 // This is a raw pointer, not reference counted, intentionally. In general | 55 // This is a raw pointer, not reference counted, intentionally. In general | 
| 55 // subclasses of DefaultWebClientObserver are not able to be refcounted | 56 // subclasses of DefaultWebClientObserver are not able to be refcounted | 
| 56 // e.g. the browser options page | 57 // e.g. the browser options page | 
| 57 ProtocolHandlerRegistry* registry_; | 58 ProtocolHandlerRegistry* registry_; | 
| 58 | 59 | 
| 59 DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver); | 60 DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver); | 
| 60 }; | 61 }; | 
| 61 | 62 | 
| 63 // The tersely named |Delegate| class provides an interface for interacting | |
| 
 
James Hawkins
2012/07/17 00:45:28
nit: I'd keep subjective terms out of the comments
 
Steve McKay
2012/07/17 01:12:42
Are you referencing the user of "tersely named"? I
 
 | |
| 64 // asynchronously with the underlying OS for the purposes of registering | |
| 65 // Chrome as the default handler for specific protocols. | |
| 66 // | |
| 62 // TODO(koz): Refactor this to eliminate the unnecessary virtuals. All that | 67 // TODO(koz): Refactor this to eliminate the unnecessary virtuals. All that | 
| 63 // should be needed is a way to ensure that the list of websafe protocols is | 68 // should be needed is a way to ensure that the list of websafe protocols is | 
| 64 // updated. | 69 // updated. | 
| 65 class Delegate { | 70 class Delegate { | 
| 66 public: | 71 public: | 
| 67 virtual ~Delegate(); | 72 virtual ~Delegate(); | 
| 68 virtual void RegisterExternalHandler(const std::string& protocol); | 73 virtual void RegisterExternalHandler(const std::string& protocol); | 
| 69 virtual void DeregisterExternalHandler(const std::string& protocol); | 74 virtual void DeregisterExternalHandler(const std::string& protocol); | 
| 70 virtual bool IsExternalHandlerRegistered(const std::string& protocol); | 75 virtual bool IsExternalHandlerRegistered(const std::string& protocol); | 
| 71 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( | 76 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( | 
| 72 ShellIntegration::DefaultWebClientObserver* observer, | 77 ShellIntegration::DefaultWebClientObserver* observer, | 
| 73 const std::string& protocol); | 78 const std::string& protocol); | 
| 74 virtual DefaultClientObserver* CreateShellObserver( | 79 virtual DefaultClientObserver* CreateShellObserver( | 
| 75 ProtocolHandlerRegistry* registry); | 80 ProtocolHandlerRegistry* registry); | 
| 76 virtual void RegisterWithOSAsDefaultClient( | 81 virtual void RegisterWithOSAsDefaultClient( | 
| 77 const std::string& protocol, | 82 const std::string& protocol, | 
| 78 ProtocolHandlerRegistry* registry); | 83 ProtocolHandlerRegistry* registry); | 
| 79 }; | 84 }; | 
| 80 | 85 | 
| 81 typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap; | 86 typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap; | 
| 82 typedef std::vector<ProtocolHandler> ProtocolHandlerList; | 87 typedef std::vector<ProtocolHandler> ProtocolHandlerList; | 
| 83 typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap; | 88 typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap; | 
| 84 typedef std::vector<DefaultClientObserver*> DefaultClientObserverList; | 89 typedef std::vector<DefaultClientObserver*> DefaultClientObserverList; | 
| 85 | 90 | 
| 86 ProtocolHandlerRegistry(Profile* profile, Delegate* 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(); | |
| 87 | 98 | 
| 88 // Called when a site tries to register as a protocol handler. If the request | 99 // Called when a site tries to register as a protocol handler. If the request | 
| 89 // can be handled silently by the registry - either to ignore the request | 100 // can be handled silently by the registry - either to ignore the request | 
| 90 // or to update an existing handler - the request will succeed. If this | 101 // or to update an existing handler - the request will succeed. If this | 
| 91 // function returns false the user needs to be prompted for confirmation. | 102 // function returns false the user needs to be prompted for confirmation. | 
| 92 bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler); | 103 bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler); | 
| 93 | 104 | 
| 94 // Called when the user accepts the registration of a given protocol handler. | 105 // Called when the user accepts the registration of a given protocol handler. | 
| 95 void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler); | 106 void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler); | 
| 96 | 107 | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 109 // Returns a list of protocol handlers that can be replaced by the given | 120 // Returns a list of protocol handlers that can be replaced by the given | 
| 110 // handler. | 121 // handler. | 
| 111 ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const; | 122 ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const; | 
| 112 | 123 | 
| 113 // Clears the default for the provided protocol. | 124 // Clears the default for the provided protocol. | 
| 114 void ClearDefault(const std::string& scheme); | 125 void ClearDefault(const std::string& scheme); | 
| 115 | 126 | 
| 116 // Returns true if this handler is the default handler for its protocol. | 127 // Returns true if this handler is the default handler for its protocol. | 
| 117 bool IsDefault(const ProtocolHandler& handler) const; | 128 bool IsDefault(const ProtocolHandler& handler) const; | 
| 118 | 129 | 
| 119 // Loads a user's registered protocol handlers. | 130 // Initializes default protocol settings and loads them from prefs. | 
| 120 void Load(); | 131 // This method must be called to complete initialization of the | 
| 132 // registry after creation, and prior to use. | |
| 133 void InitProtocolSettings(); | |
| 121 | 134 | 
| 122 // Returns the offset in the list of handlers for a protocol of the default | 135 // Returns the offset in the list of handlers for a protocol of the default | 
| 123 // handler for that protocol. | 136 // handler for that protocol. | 
| 124 int GetHandlerIndex(const std::string& scheme) const; | 137 int GetHandlerIndex(const std::string& scheme) const; | 
| 125 | 138 | 
| 126 // Get the list of protocol handlers for the given scheme. | 139 // Get the list of protocol handlers for the given scheme. | 
| 127 ProtocolHandlerList GetHandlersFor(const std::string& scheme) const; | 140 ProtocolHandlerList GetHandlersFor(const std::string& scheme) const; | 
| 128 | 141 | 
| 129 // Get the list of ignored protocol handlers. | 142 // Get the list of ignored protocol handlers. | 
| 130 ProtocolHandlerList GetIgnoredHandlers(); | 143 ProtocolHandlerList GetIgnoredHandlers(); | 
| (...skipping 17 matching lines...) Expand all Loading... | |
| 148 | 161 | 
| 149 // Returns true if an equivalent protocol handler is being ignored. | 162 // Returns true if an equivalent protocol handler is being ignored. | 
| 150 bool HasIgnoredEquivalent(const ProtocolHandler& handler) const; | 163 bool HasIgnoredEquivalent(const ProtocolHandler& handler) const; | 
| 151 | 164 | 
| 152 // Causes the given protocol handler to not be ignored anymore. | 165 // Causes the given protocol handler to not be ignored anymore. | 
| 153 void RemoveIgnoredHandler(const ProtocolHandler& handler); | 166 void RemoveIgnoredHandler(const ProtocolHandler& handler); | 
| 154 | 167 | 
| 155 // Returns true if the protocol has a default protocol handler. | 168 // Returns true if the protocol has a default protocol handler. | 
| 156 bool IsHandledProtocol(const std::string& scheme) const; | 169 bool IsHandledProtocol(const std::string& scheme) const; | 
| 157 | 170 | 
| 158 // Returns true if the protocol has a default protocol handler. | |
| 159 // Should be called only from the IO thread. | |
| 160 bool IsHandledProtocolIO(const std::string& scheme) const; | |
| 161 | |
| 162 // Removes the given protocol handler from the registry. | 171 // Removes the given protocol handler from the registry. | 
| 163 void RemoveHandler(const ProtocolHandler& handler); | 172 void RemoveHandler(const ProtocolHandler& handler); | 
| 164 | 173 | 
| 165 // Remove the default handler for the given protocol. | 174 // Remove the default handler for the given protocol. | 
| 166 void RemoveDefaultHandler(const std::string& scheme); | 175 void RemoveDefaultHandler(const std::string& scheme); | 
| 167 | 176 | 
| 168 // Returns the default handler for this protocol, or an empty handler if none | 177 // Returns the default handler for this protocol, or an empty handler if none | 
| 169 // exists. | 178 // exists. | 
| 170 const ProtocolHandler& GetHandlerFor(const std::string& scheme) const; | 179 const ProtocolHandler& GetHandlerFor(const std::string& scheme) const; | 
| 171 | 180 | 
| 172 // Creates a URL request job for the given request if there is a matching | |
| 173 // protocol handler, returns NULL otherwise. | |
| 174 net::URLRequestJob* MaybeCreateJob(net::URLRequest* request) const; | |
| 175 | |
| 176 // Puts this registry in the enabled state - registered protocol handlers | 181 // Puts this registry in the enabled state - registered protocol handlers | 
| 177 // will handle requests. | 182 // will handle requests. | 
| 178 void Enable(); | 183 void Enable(); | 
| 179 | 184 | 
| 180 // Puts this registry in the disabled state - registered protocol handlers | 185 // Puts this registry in the disabled state - registered protocol handlers | 
| 181 // will not handle requests. | 186 // will not handle requests. | 
| 182 void Disable(); | 187 void Disable(); | 
| 183 | 188 | 
| 184 // This is called by the UI thread when the system is shutting down. This | 189 // This is called by the UI thread when the system is shutting down. This | 
| 185 // does finalization which must be done on the UI thread. | 190 // does finalization which must be done on the UI thread. | 
| 186 void Finalize(); | 191 virtual void Shutdown() OVERRIDE; | 
| 187 | 192 | 
| 188 // Registers the preferences that we store registered protocol handlers in. | 193 // Registers the preferences that we store registered protocol handlers in. | 
| 189 static void RegisterPrefs(PrefService* prefService); | 194 static void RegisterPrefs(PrefService* prefService); | 
| 190 | 195 | 
| 191 bool enabled() const { return enabled_; } | 196 bool enabled() const { return enabled_; } | 
| 192 | 197 | 
| 193 // Add a predefined protocol handler. This has to be called before the first | 198 // Add a predefined protocol handler. This has to be called before the first | 
| 194 // load command was issued, otherwise the command will be ignored. | 199 // load command was issued, otherwise the command will be ignored. | 
| 195 void AddPredefinedHandler(const ProtocolHandler& handler); | 200 void AddPredefinedHandler(const ProtocolHandler& handler); | 
| 196 | 201 | 
| 197 private: | 202 private: | 
| 198 friend class base::DeleteHelper<ProtocolHandlerRegistry>; | 203 friend class base::DeleteHelper<ProtocolHandlerRegistry>; | 
| 199 friend struct content::BrowserThread::DeleteOnThread< | 204 friend struct content::BrowserThread::DeleteOnThread< | 
| 200 content::BrowserThread::IO>; | 205 content::BrowserThread::IO>; | 
| 201 friend class ProtocolHandlerRegistryTest; | 206 friend class ProtocolHandlerRegistryTest; | 
| 202 friend class RegisterProtocolHandlerBrowserTest; | 207 friend class RegisterProtocolHandlerBrowserTest; | 
| 203 | 208 | 
| 204 ~ProtocolHandlerRegistry(); | 209 // Forward declaration of our internal implementation classes. | 
| 
 
James Hawkins
2012/07/17 00:45:28
nit: s/our/the/
 
 | |
| 210 class Core; | |
| 211 class URLInterceptor; | |
| 205 | 212 | 
| 206 // Puts the given handler at the top of the list of handlers for its | 213 // Puts the given handler at the top of the list of handlers for its | 
| 207 // protocol. | 214 // protocol. | 
| 208 void PromoteHandler(const ProtocolHandler& handler); | 215 void PromoteHandler(const ProtocolHandler& handler); | 
| 209 | 216 | 
| 210 // Clears the default for the provided protocol. | |
| 211 // Should be called only from the IO thread. | |
| 212 void ClearDefaultIO(const std::string& scheme); | |
| 213 | |
| 214 // Makes this ProtocolHandler the default handler for its protocol. | |
| 215 // Should be called only from the IO thread. | |
| 216 void SetDefaultIO(const ProtocolHandler& handler); | |
| 217 | |
| 218 // Indicate that the registry has been enabled in the IO thread's copy of the | |
| 219 // data. | |
| 220 void EnableIO() { enabled_io_ = true; } | |
| 221 | |
| 222 // Indicate that the registry has been disabled in the IO thread's copy of | |
| 223 // the data. | |
| 224 void DisableIO() { enabled_io_ = false; } | |
| 225 | |
| 226 // Saves a user's registered protocol handlers. | 217 // Saves a user's registered protocol handlers. | 
| 227 void Save(); | 218 void Save(); | 
| 228 | 219 | 
| 229 // Returns a pointer to the list of handlers registered for the given scheme, | 220 // Returns a pointer to the list of handlers registered for the given scheme, | 
| 230 // or NULL if there are none. | 221 // or NULL if there are none. | 
| 231 const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const; | 222 const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const; | 
| 232 | 223 | 
| 233 // Makes this ProtocolHandler the default handler for its protocol. | 224 // Makes this ProtocolHandler the default handler for its protocol. | 
| 234 void SetDefault(const ProtocolHandler& handler); | 225 void SetDefault(const ProtocolHandler& handler); | 
| 235 | 226 | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 // The Profile that owns this ProtocolHandlerRegistry. | 261 // The Profile that owns this ProtocolHandlerRegistry. | 
| 271 Profile* profile_; | 262 Profile* profile_; | 
| 272 | 263 | 
| 273 // The Delegate that registers / deregisters external handlers on our behalf. | 264 // The Delegate that registers / deregisters external handlers on our behalf. | 
| 274 scoped_ptr<Delegate> delegate_; | 265 scoped_ptr<Delegate> delegate_; | 
| 275 | 266 | 
| 276 // If false then registered protocol handlers will not be used to handle | 267 // If false then registered protocol handlers will not be used to handle | 
| 277 // requests. | 268 // requests. | 
| 278 bool enabled_; | 269 bool enabled_; | 
| 279 | 270 | 
| 280 // Copy of enabled_ that is only accessed on the IO thread. | |
| 281 bool enabled_io_; | |
| 282 | |
| 283 // Whether or not we are loading. | 271 // Whether or not we are loading. | 
| 284 bool is_loading_; | 272 bool is_loading_; | 
| 285 | 273 | 
| 286 // When the table gets loaded this flag will be set and any further calls to | 274 // When the table gets loaded this flag will be set and any further calls to | 
| 287 // AddPredefinedHandler will be rejected. | 275 // AddPredefinedHandler will be rejected. | 
| 288 bool is_loaded_; | 276 bool is_loaded_; | 
| 289 | 277 | 
| 278 scoped_refptr<Core> core_; | |
| 
 
James Hawkins
2012/07/17 00:45:28
nit: Document.
 
Steve McKay
2012/07/17 01:12:42
Done.
 
 | |
| 279 | |
| 290 DefaultClientObserverList default_client_observers_; | 280 DefaultClientObserverList default_client_observers_; | 
| 291 | 281 | 
| 292 // Copy of default_handlers_ that is only accessed on the IO thread. | |
| 293 ProtocolHandlerMap default_handlers_io_; | |
| 294 | |
| 295 DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry); | 282 DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry); | 
| 296 }; | 283 }; | 
| 297 #endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ | 284 #endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_ | 
| OLD | NEW |