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.
5 #ifndef CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
6 #define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
12 #include "base/basictypes.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/sequenced_task_runner_helpers.h"
16 #include "base/values.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/shell_integration.h"
19 #include "chrome/common/custom_handlers/protocol_handler.h"
20 #include "components/keyed_service/core/keyed_service.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/notification_service.h"
23 #include "net/url_request/url_request.h"
24 #include "net/url_request/url_request_job.h"
25 #include "net/url_request/url_request_job_factory.h"
27 namespace user_prefs
{
28 class PrefRegistrySyncable
;
31 // This is where handlers for protocols registered with
32 // navigator.registerProtocolHandler() are registered. Each Profile owns an
33 // instance of this class, which is initialized on browser start through
34 // Profile::InitRegisteredProtocolHandlers(), and they should be the only
35 // instances of this class.
36 class ProtocolHandlerRegistry
: public KeyedService
{
40 USER
, // The handler was installed by user
41 POLICY
, // The handler was installed by policy
43 // Provides notification of when the OS level user agent settings
45 class DefaultClientObserver
46 : public ShellIntegration::DefaultWebClientObserver
{
48 explicit DefaultClientObserver(ProtocolHandlerRegistry
* registry
);
49 virtual ~DefaultClientObserver();
51 // Get response from the worker regarding whether Chrome is the default
52 // handler for the protocol.
53 virtual void SetDefaultWebClientUIState(
54 ShellIntegration::DefaultWebClientUIState state
) OVERRIDE
;
56 virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE
;
58 // Give the observer a handle to the worker, so we can find out the protocol
59 // when we're called and also tell the worker if we get deleted.
60 void SetWorker(ShellIntegration::DefaultProtocolClientWorker
* worker
);
63 ShellIntegration::DefaultProtocolClientWorker
* worker_
;
66 virtual bool IsOwnedByWorker() OVERRIDE
;
68 // This is a raw pointer, not reference counted, intentionally. In general
69 // subclasses of DefaultWebClientObserver are not able to be refcounted
70 // e.g. the browser options page
71 ProtocolHandlerRegistry
* registry_
;
73 DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver
);
76 // |Delegate| provides an interface for interacting asynchronously
77 // with the underlying OS for the purposes of registering Chrome
78 // as the default handler for specific protocols.
82 virtual void RegisterExternalHandler(const std::string
& protocol
);
83 virtual void DeregisterExternalHandler(const std::string
& protocol
);
84 virtual bool IsExternalHandlerRegistered(const std::string
& protocol
);
85 virtual ShellIntegration::DefaultProtocolClientWorker
* CreateShellWorker(
86 ShellIntegration::DefaultWebClientObserver
* observer
,
87 const std::string
& protocol
);
88 virtual DefaultClientObserver
* CreateShellObserver(
89 ProtocolHandlerRegistry
* registry
);
90 virtual void RegisterWithOSAsDefaultClient(
91 const std::string
& protocol
,
92 ProtocolHandlerRegistry
* registry
);
95 // Forward declaration of the internal implementation class.
96 class IOThreadDelegate
;
98 // JobInterceptorFactory intercepts URLRequestJob creation for URLRequests the
99 // ProtocolHandlerRegistry is registered to handle. When no handler is
100 // registered, the URLRequest is passed along to the chained
101 // URLRequestJobFactory (set with |JobInterceptorFactory::Chain|).
102 // JobInterceptorFactory's are created via
103 // |ProtocolHandlerRegistry::CreateJobInterceptorFactory|.
104 class JobInterceptorFactory
: public net::URLRequestJobFactory
{
106 // |io_thread_delegate| is used to perform actual job creation work.
107 explicit JobInterceptorFactory(IOThreadDelegate
* io_thread_delegate
);
108 virtual ~JobInterceptorFactory();
110 // |job_factory| is set as the URLRequestJobFactory where requests are
111 // forwarded if JobInterceptorFactory decides to pass on them.
112 void Chain(scoped_ptr
<net::URLRequestJobFactory
> job_factory
);
114 // URLRequestJobFactory implementation.
115 virtual net::URLRequestJob
* MaybeCreateJobWithProtocolHandler(
116 const std::string
& scheme
,
117 net::URLRequest
* request
,
118 net::NetworkDelegate
* network_delegate
) const OVERRIDE
;
119 virtual bool IsHandledProtocol(const std::string
& scheme
) const OVERRIDE
;
120 virtual bool IsHandledURL(const GURL
& url
) const OVERRIDE
;
121 virtual bool IsSafeRedirectTarget(const GURL
& location
) const OVERRIDE
;
124 // When JobInterceptorFactory decides to pass on particular requests,
125 // they're forwarded to the chained URLRequestJobFactory, |job_factory_|.
126 scoped_ptr
<URLRequestJobFactory
> job_factory_
;
127 // |io_thread_delegate_| performs the actual job creation decisions by
128 // mirroring the ProtocolHandlerRegistry on the IO thread.
129 scoped_refptr
<IOThreadDelegate
> io_thread_delegate_
;
131 DISALLOW_COPY_AND_ASSIGN(JobInterceptorFactory
);
134 typedef std::map
<std::string
, ProtocolHandler
> ProtocolHandlerMap
;
135 typedef std::vector
<ProtocolHandler
> ProtocolHandlerList
;
136 typedef std::map
<std::string
, ProtocolHandlerList
> ProtocolHandlerMultiMap
;
137 typedef std::vector
<DefaultClientObserver
*> DefaultClientObserverList
;
139 // Creates a new instance. Assumes ownership of |delegate|.
140 ProtocolHandlerRegistry(content::BrowserContext
* context
, Delegate
* delegate
);
141 virtual ~ProtocolHandlerRegistry();
143 // Returns a net::URLRequestJobFactory suitable for use on the IO thread, but
144 // is initialized on the UI thread.
145 scoped_ptr
<JobInterceptorFactory
> CreateJobInterceptorFactory();
147 // Called when a site tries to register as a protocol handler. If the request
148 // can be handled silently by the registry - either to ignore the request
149 // or to update an existing handler - the request will succeed. If this
150 // function returns false the user needs to be prompted for confirmation.
151 bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler
& handler
);
153 // Called when the user accepts the registration of a given protocol handler.
154 void OnAcceptRegisterProtocolHandler(const ProtocolHandler
& handler
);
156 // Called when the user denies the registration of a given protocol handler.
157 void OnDenyRegisterProtocolHandler(const ProtocolHandler
& handler
);
159 // Called when the user indicates that they don't want to be asked about the
160 // given protocol handler again.
161 void OnIgnoreRegisterProtocolHandler(const ProtocolHandler
& handler
);
163 // Removes all handlers that have the same origin and protocol as the given
164 // one and installs the given handler. Returns true if any protocol handlers
166 bool AttemptReplace(const ProtocolHandler
& handler
);
168 // Returns a list of protocol handlers that can be replaced by the given
170 ProtocolHandlerList
GetReplacedHandlers(const ProtocolHandler
& handler
) const;
172 // Clears the default for the provided protocol.
173 void ClearDefault(const std::string
& scheme
);
175 // Returns true if this handler is the default handler for its protocol.
176 bool IsDefault(const ProtocolHandler
& handler
) const;
178 // Initializes default protocol settings and loads them from prefs.
179 // This method must be called to complete initialization of the
180 // registry after creation, and prior to use.
181 void InitProtocolSettings();
183 // Returns the offset in the list of handlers for a protocol of the default
184 // handler for that protocol.
185 int GetHandlerIndex(const std::string
& scheme
) const;
187 // Get the list of protocol handlers for the given scheme.
188 ProtocolHandlerList
GetHandlersFor(const std::string
& scheme
) const;
190 // Get the list of ignored protocol handlers.
191 ProtocolHandlerList
GetIgnoredHandlers();
193 // Yields a list of the protocols that have handlers registered in this
195 void GetRegisteredProtocols(std::vector
<std::string
>* output
) const;
197 // Returns true if we allow websites to register handlers for the given
199 bool CanSchemeBeOverridden(const std::string
& scheme
) const;
201 // Returns true if an identical protocol handler has already been registered.
202 bool IsRegistered(const ProtocolHandler
& handler
) const;
204 // Returns true if an identical protocol handler is being ignored.
205 bool IsIgnored(const ProtocolHandler
& handler
) const;
207 // Returns true if an equivalent protocol handler has already been registered.
208 bool HasRegisteredEquivalent(const ProtocolHandler
& handler
) const;
210 // Returns true if an equivalent protocol handler is being ignored.
211 bool HasIgnoredEquivalent(const ProtocolHandler
& handler
) const;
213 // Causes the given protocol handler to not be ignored anymore.
214 void RemoveIgnoredHandler(const ProtocolHandler
& handler
);
216 // Returns true if the protocol has a default protocol handler.
217 bool IsHandledProtocol(const std::string
& scheme
) const;
219 // Removes the given protocol handler from the registry.
220 void RemoveHandler(const ProtocolHandler
& handler
);
222 // Remove the default handler for the given protocol.
223 void RemoveDefaultHandler(const std::string
& scheme
);
225 // Returns the default handler for this protocol, or an empty handler if none
227 const ProtocolHandler
& GetHandlerFor(const std::string
& scheme
) const;
229 // Puts this registry in the enabled state - registered protocol handlers
230 // will handle requests.
233 // Puts this registry in the disabled state - registered protocol handlers
234 // will not handle requests.
237 // This is called by the UI thread when the system is shutting down. This
238 // does finalization which must be done on the UI thread.
239 virtual void Shutdown() OVERRIDE
;
241 // Registers the preferences that we store registered protocol handlers in.
242 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
);
244 bool enabled() const { return enabled_
; }
246 // Add a predefined protocol handler. This has to be called before the first
247 // load command was issued, otherwise the command will be ignored.
248 void AddPredefinedHandler(const ProtocolHandler
& handler
);
251 friend class base::DeleteHelper
<ProtocolHandlerRegistry
>;
252 friend struct content::BrowserThread::DeleteOnThread
<
253 content::BrowserThread::IO
>;
255 // for access to InstallDefaultsForChromeOS
256 friend class ProtocolHandlerRegistryFactory
;
258 friend class ProtocolHandlerRegistryTest
;
259 friend class RegisterProtocolHandlerBrowserTest
;
261 // Puts the given handler at the top of the list of handlers for its
263 void PromoteHandler(const ProtocolHandler
& handler
);
265 // Saves a user's registered protocol handlers.
268 // Returns a pointer to the list of handlers registered for the given scheme,
269 // or NULL if there are none.
270 const ProtocolHandlerList
* GetHandlerList(const std::string
& scheme
) const;
272 // Install default protocol handlers for chromeos which must be done
273 // prior to calling InitProtocolSettings.
274 void InstallDefaultsForChromeOS();
276 // Makes this ProtocolHandler the default handler for its protocol.
277 void SetDefault(const ProtocolHandler
& handler
);
279 // Insert the given ProtocolHandler into the registry.
280 void InsertHandler(const ProtocolHandler
& handler
);
282 // Returns a JSON list of protocol handlers. The caller is responsible for
283 // deleting this Value.
284 base::Value
* EncodeRegisteredHandlers();
286 // Returns a JSON list of ignored protocol handlers. The caller is
287 // responsible for deleting this Value.
288 base::Value
* EncodeIgnoredHandlers();
290 // Sends a notification of the given type to the NotificationService.
291 void NotifyChanged();
293 // Registers a new protocol handler.
294 void RegisterProtocolHandler(const ProtocolHandler
& handler
,
295 const HandlerSource source
);
297 // Registers protocol handlers from the preference.
298 void RegisterProtocolHandlersFromPref(const char* pref_name
,
299 const HandlerSource source
);
301 // Get the DictionaryValues stored under the given pref name that are valid
302 // ProtocolHandler values.
303 std::vector
<const base::DictionaryValue
*> GetHandlersFromPref(
304 const char* pref_name
) const;
306 // Ignores future requests to register the given protocol handler.
307 void IgnoreProtocolHandler(const ProtocolHandler
& handler
,
308 const HandlerSource source
);
310 // Ignores protocol handlers from the preference.
311 void IgnoreProtocolHandlersFromPref(const char* pref_name
,
312 const HandlerSource source
);
314 // Verifies if the handler exists in the map.
315 bool HandlerExists(const ProtocolHandler
& handler
,
316 ProtocolHandlerMultiMap
* map
);
318 // Verifies if the handler exists in the list.
319 bool HandlerExists(const ProtocolHandler
& handler
,
320 const ProtocolHandlerList
& list
);
322 // Erases the handler that is guaranteed to exist from the map.
323 void EraseHandler(const ProtocolHandler
& handler
,
324 ProtocolHandlerMultiMap
* map
);
326 // Erases the handler that is guaranteed to exist from the list.
327 void EraseHandler(const ProtocolHandler
& handler
, ProtocolHandlerList
* list
);
329 // Map from protocols (strings) to protocol handlers.
330 ProtocolHandlerMultiMap protocol_handlers_
;
332 // Protocol handlers that the user has told us to ignore.
333 ProtocolHandlerList ignored_protocol_handlers_
;
335 // These maps track the source of protocol handler registrations for the
336 // purposes of disallowing the removal of handlers that are registered by
337 // policy. Every entry in protocol_handlers_ should exist in at least one of
338 // the user or policy maps.
339 ProtocolHandlerMultiMap user_protocol_handlers_
;
340 ProtocolHandlerMultiMap policy_protocol_handlers_
;
342 // These lists track the source of protocol handlers that were ignored, for
343 // the purposes of disallowing the removal of handlers that are ignored by
344 // policy. Every entry in ignored_protocol_handlers_ should exist in at least
345 // one of the user or policy lists.
346 ProtocolHandlerList user_ignored_protocol_handlers_
;
347 ProtocolHandlerList policy_ignored_protocol_handlers_
;
349 // Protocol handlers that are the defaults for a given protocol.
350 ProtocolHandlerMap default_handlers_
;
352 // The browser context that owns this ProtocolHandlerRegistry.
353 content::BrowserContext
* context_
;
355 // The Delegate that registers / deregisters external handlers on our behalf.
356 scoped_ptr
<Delegate
> delegate_
;
358 // If false then registered protocol handlers will not be used to handle
362 // Whether or not we are loading.
365 // When the table gets loaded this flag will be set and any further calls to
366 // AddPredefinedHandler will be rejected.
369 // Copy of registry data for use on the IO thread. Changes to the registry
370 // are posted to the IO thread where updates are applied to this object.
371 scoped_refptr
<IOThreadDelegate
> io_thread_delegate_
;
373 DefaultClientObserverList default_client_observers_
;
375 DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry
);
377 #endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_