Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / custom_handlers / protocol_handler_registry.h
blobf43183383635fb9fe3947a5e973227d70febc198
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_
8 #include <map>
9 #include <string>
10 #include <vector>
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/browser_context_keyed_service/browser_context_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 BrowserContextKeyedService {
38 public:
39 // Provides notification of when the OS level user agent settings
40 // are changed.
41 class DefaultClientObserver
42 : public ShellIntegration::DefaultWebClientObserver {
43 public:
44 explicit DefaultClientObserver(ProtocolHandlerRegistry* registry);
45 virtual ~DefaultClientObserver();
47 // Get response from the worker regarding whether Chrome is the default
48 // handler for the protocol.
49 virtual void SetDefaultWebClientUIState(
50 ShellIntegration::DefaultWebClientUIState state) OVERRIDE;
52 virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE;
54 // Give the observer a handle to the worker, so we can find out the protocol
55 // when we're called and also tell the worker if we get deleted.
56 void SetWorker(ShellIntegration::DefaultProtocolClientWorker* worker);
58 protected:
59 ShellIntegration::DefaultProtocolClientWorker* worker_;
61 private:
62 virtual bool IsOwnedByWorker() OVERRIDE;
64 // This is a raw pointer, not reference counted, intentionally. In general
65 // subclasses of DefaultWebClientObserver are not able to be refcounted
66 // e.g. the browser options page
67 ProtocolHandlerRegistry* registry_;
69 DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver);
72 // |Delegate| provides an interface for interacting asynchronously
73 // with the underlying OS for the purposes of registering Chrome
74 // as the default handler for specific protocols.
75 class Delegate {
76 public:
77 virtual ~Delegate();
78 virtual void RegisterExternalHandler(const std::string& protocol);
79 virtual void DeregisterExternalHandler(const std::string& protocol);
80 virtual bool IsExternalHandlerRegistered(const std::string& protocol);
81 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
82 ShellIntegration::DefaultWebClientObserver* observer,
83 const std::string& protocol);
84 virtual DefaultClientObserver* CreateShellObserver(
85 ProtocolHandlerRegistry* registry);
86 virtual void RegisterWithOSAsDefaultClient(
87 const std::string& protocol,
88 ProtocolHandlerRegistry* registry);
91 // Forward declaration of the internal implementation class.
92 class IOThreadDelegate;
94 // JobInterceptorFactory intercepts URLRequestJob creation for URLRequests the
95 // ProtocolHandlerRegistry is registered to handle. When no handler is
96 // registered, the URLRequest is passed along to the chained
97 // URLRequestJobFactory (set with |JobInterceptorFactory::Chain|).
98 // JobInterceptorFactory's are created via
99 // |ProtocolHandlerRegistry::CreateJobInterceptorFactory|.
100 class JobInterceptorFactory : public net::URLRequestJobFactory {
101 public:
102 // |io_thread_delegate| is used to perform actual job creation work.
103 explicit JobInterceptorFactory(IOThreadDelegate* io_thread_delegate);
104 virtual ~JobInterceptorFactory();
106 // |job_factory| is set as the URLRequestJobFactory where requests are
107 // forwarded if JobInterceptorFactory decides to pass on them.
108 void Chain(scoped_ptr<net::URLRequestJobFactory> job_factory);
110 // URLRequestJobFactory implementation.
111 virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
112 const std::string& scheme,
113 net::URLRequest* request,
114 net::NetworkDelegate* network_delegate) const OVERRIDE;
115 virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE;
116 virtual bool IsHandledURL(const GURL& url) const OVERRIDE;
117 virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE;
119 private:
120 // When JobInterceptorFactory decides to pass on particular requests,
121 // they're forwarded to the chained URLRequestJobFactory, |job_factory_|.
122 scoped_ptr<URLRequestJobFactory> job_factory_;
123 // |io_thread_delegate_| performs the actual job creation decisions by
124 // mirroring the ProtocolHandlerRegistry on the IO thread.
125 scoped_refptr<IOThreadDelegate> io_thread_delegate_;
127 DISALLOW_COPY_AND_ASSIGN(JobInterceptorFactory);
130 typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
131 typedef std::vector<ProtocolHandler> ProtocolHandlerList;
132 typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
133 typedef std::vector<DefaultClientObserver*> DefaultClientObserverList;
135 // Creates a new instance. Assumes ownership of |delegate|.
136 ProtocolHandlerRegistry(Profile* profile, Delegate* delegate);
137 virtual ~ProtocolHandlerRegistry();
139 // Returns a net::URLRequestJobFactory suitable for use on the IO thread, but
140 // is initialized on the UI thread.
141 scoped_ptr<JobInterceptorFactory> CreateJobInterceptorFactory();
143 // Called when a site tries to register as a protocol handler. If the request
144 // can be handled silently by the registry - either to ignore the request
145 // or to update an existing handler - the request will succeed. If this
146 // function returns false the user needs to be prompted for confirmation.
147 bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler);
149 // Called when the user accepts the registration of a given protocol handler.
150 void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler);
152 // Called when the user denies the registration of a given protocol handler.
153 void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler);
155 // Called when the user indicates that they don't want to be asked about the
156 // given protocol handler again.
157 void OnIgnoreRegisterProtocolHandler(const ProtocolHandler& handler);
159 // Removes all handlers that have the same origin and protocol as the given
160 // one and installs the given handler. Returns true if any protocol handlers
161 // were replaced.
162 bool AttemptReplace(const ProtocolHandler& handler);
164 // Returns a list of protocol handlers that can be replaced by the given
165 // handler.
166 ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const;
168 // Clears the default for the provided protocol.
169 void ClearDefault(const std::string& scheme);
171 // Returns true if this handler is the default handler for its protocol.
172 bool IsDefault(const ProtocolHandler& handler) const;
174 // Initializes default protocol settings and loads them from prefs.
175 // This method must be called to complete initialization of the
176 // registry after creation, and prior to use.
177 void InitProtocolSettings();
179 // Returns the offset in the list of handlers for a protocol of the default
180 // handler for that protocol.
181 int GetHandlerIndex(const std::string& scheme) const;
183 // Get the list of protocol handlers for the given scheme.
184 ProtocolHandlerList GetHandlersFor(const std::string& scheme) const;
186 // Get the list of ignored protocol handlers.
187 ProtocolHandlerList GetIgnoredHandlers();
189 // Yields a list of the protocols that have handlers registered in this
190 // registry.
191 void GetRegisteredProtocols(std::vector<std::string>* output) const;
193 // Returns true if we allow websites to register handlers for the given
194 // scheme.
195 bool CanSchemeBeOverridden(const std::string& scheme) const;
197 // Returns true if an identical protocol handler has already been registered.
198 bool IsRegistered(const ProtocolHandler& handler) const;
200 // Returns true if an identical protocol handler is being ignored.
201 bool IsIgnored(const ProtocolHandler& handler) const;
203 // Returns true if an equivalent protocol handler has already been registered.
204 bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
206 // Returns true if an equivalent protocol handler is being ignored.
207 bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
209 // Causes the given protocol handler to not be ignored anymore.
210 void RemoveIgnoredHandler(const ProtocolHandler& handler);
212 // Returns true if the protocol has a default protocol handler.
213 bool IsHandledProtocol(const std::string& scheme) const;
215 // Removes the given protocol handler from the registry.
216 void RemoveHandler(const ProtocolHandler& handler);
218 // Remove the default handler for the given protocol.
219 void RemoveDefaultHandler(const std::string& scheme);
221 // Returns the default handler for this protocol, or an empty handler if none
222 // exists.
223 const ProtocolHandler& GetHandlerFor(const std::string& scheme) const;
225 // Puts this registry in the enabled state - registered protocol handlers
226 // will handle requests.
227 void Enable();
229 // Puts this registry in the disabled state - registered protocol handlers
230 // will not handle requests.
231 void Disable();
233 // This is called by the UI thread when the system is shutting down. This
234 // does finalization which must be done on the UI thread.
235 virtual void Shutdown() OVERRIDE;
237 // Registers the preferences that we store registered protocol handlers in.
238 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
240 bool enabled() const { return enabled_; }
242 // Add a predefined protocol handler. This has to be called before the first
243 // load command was issued, otherwise the command will be ignored.
244 void AddPredefinedHandler(const ProtocolHandler& handler);
246 private:
247 friend class base::DeleteHelper<ProtocolHandlerRegistry>;
248 friend struct content::BrowserThread::DeleteOnThread<
249 content::BrowserThread::IO>;
251 // for access to InstallDefaultsForChromeOS
252 friend class ProtocolHandlerRegistryFactory;
254 friend class ProtocolHandlerRegistryTest;
255 friend class RegisterProtocolHandlerBrowserTest;
257 // Puts the given handler at the top of the list of handlers for its
258 // protocol.
259 void PromoteHandler(const ProtocolHandler& handler);
261 // Saves a user's registered protocol handlers.
262 void Save();
264 // Returns a pointer to the list of handlers registered for the given scheme,
265 // or NULL if there are none.
266 const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const;
268 // Install default protocol handlers for chromeos which must be done
269 // prior to calling InitProtocolSettings.
270 void InstallDefaultsForChromeOS();
272 // Makes this ProtocolHandler the default handler for its protocol.
273 void SetDefault(const ProtocolHandler& handler);
275 // Insert the given ProtocolHandler into the registry.
276 void InsertHandler(const ProtocolHandler& handler);
278 // Returns a JSON list of protocol handlers. The caller is responsible for
279 // deleting this Value.
280 base::Value* EncodeRegisteredHandlers();
282 // Returns a JSON list of ignored protocol handlers. The caller is
283 // responsible for deleting this Value.
284 base::Value* EncodeIgnoredHandlers();
286 // Sends a notification of the given type to the NotificationService.
287 void NotifyChanged();
289 // Registers a new protocol handler.
290 void RegisterProtocolHandler(const ProtocolHandler& handler);
292 // Get the DictionaryValues stored under the given pref name that are valid
293 // ProtocolHandler values.
294 std::vector<const base::DictionaryValue*> GetHandlersFromPref(
295 const char* pref_name) const;
297 // Ignores future requests to register the given protocol handler.
298 void IgnoreProtocolHandler(const ProtocolHandler& handler);
300 // Map from protocols (strings) to protocol handlers.
301 ProtocolHandlerMultiMap protocol_handlers_;
303 // Protocol handlers that the user has told us to ignore.
304 ProtocolHandlerList ignored_protocol_handlers_;
306 // Protocol handlers that are the defaults for a given protocol.
307 ProtocolHandlerMap default_handlers_;
309 // The Profile that owns this ProtocolHandlerRegistry.
310 Profile* profile_;
312 // The Delegate that registers / deregisters external handlers on our behalf.
313 scoped_ptr<Delegate> delegate_;
315 // If false then registered protocol handlers will not be used to handle
316 // requests.
317 bool enabled_;
319 // Whether or not we are loading.
320 bool is_loading_;
322 // When the table gets loaded this flag will be set and any further calls to
323 // AddPredefinedHandler will be rejected.
324 bool is_loaded_;
326 // Copy of registry data for use on the IO thread. Changes to the registry
327 // are posted to the IO thread where updates are applied to this object.
328 scoped_refptr<IOThreadDelegate> io_thread_delegate_;
330 DefaultClientObserverList default_client_observers_;
332 DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
334 #endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_