Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / custom_handlers / protocol_handler_registry.h
blob6c25ac1d7ada7493b7e958c8de2b8609a45580cd
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/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 {
38 public:
39 enum HandlerSource {
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
44 // are changed.
45 class DefaultClientObserver
46 : public ShellIntegration::DefaultWebClientObserver {
47 public:
48 explicit DefaultClientObserver(ProtocolHandlerRegistry* registry);
49 ~DefaultClientObserver() override;
51 // Get response from the worker regarding whether Chrome is the default
52 // handler for the protocol.
53 void SetDefaultWebClientUIState(
54 ShellIntegration::DefaultWebClientUIState state) override;
56 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);
62 protected:
63 ShellIntegration::DefaultProtocolClientWorker* worker_;
65 private:
66 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.
79 class Delegate {
80 public:
81 virtual ~Delegate();
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 {
105 public:
106 // |io_thread_delegate| is used to perform actual job creation work.
107 explicit JobInterceptorFactory(IOThreadDelegate* io_thread_delegate);
108 ~JobInterceptorFactory() override;
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 net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
116 const std::string& scheme,
117 net::URLRequest* request,
118 net::NetworkDelegate* network_delegate) const override;
120 net::URLRequestJob* MaybeInterceptRedirect(
121 net::URLRequest* request,
122 net::NetworkDelegate* network_delegate,
123 const GURL& location) const override;
125 net::URLRequestJob* MaybeInterceptResponse(
126 net::URLRequest* request,
127 net::NetworkDelegate* network_delegate) const override;
129 bool IsHandledProtocol(const std::string& scheme) const override;
130 bool IsHandledURL(const GURL& url) const override;
131 bool IsSafeRedirectTarget(const GURL& location) const override;
133 private:
134 // When JobInterceptorFactory decides to pass on particular requests,
135 // they're forwarded to the chained URLRequestJobFactory, |job_factory_|.
136 scoped_ptr<URLRequestJobFactory> job_factory_;
137 // |io_thread_delegate_| performs the actual job creation decisions by
138 // mirroring the ProtocolHandlerRegistry on the IO thread.
139 scoped_refptr<IOThreadDelegate> io_thread_delegate_;
141 DISALLOW_COPY_AND_ASSIGN(JobInterceptorFactory);
144 typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
145 typedef std::vector<ProtocolHandler> ProtocolHandlerList;
146 typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
147 typedef std::vector<DefaultClientObserver*> DefaultClientObserverList;
149 // Creates a new instance. Assumes ownership of |delegate|.
150 ProtocolHandlerRegistry(content::BrowserContext* context, Delegate* delegate);
151 ~ProtocolHandlerRegistry() override;
153 // Returns a net::URLRequestJobFactory suitable for use on the IO thread, but
154 // is initialized on the UI thread.
155 scoped_ptr<JobInterceptorFactory> CreateJobInterceptorFactory();
157 // Called when a site tries to register as a protocol handler. If the request
158 // can be handled silently by the registry - either to ignore the request
159 // or to update an existing handler - the request will succeed. If this
160 // function returns false the user needs to be prompted for confirmation.
161 bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler);
163 // Called when the user accepts the registration of a given protocol handler.
164 void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler);
166 // Called when the user denies the registration of a given protocol handler.
167 void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler);
169 // Called when the user indicates that they don't want to be asked about the
170 // given protocol handler again.
171 void OnIgnoreRegisterProtocolHandler(const ProtocolHandler& handler);
173 // Removes all handlers that have the same origin and protocol as the given
174 // one and installs the given handler. Returns true if any protocol handlers
175 // were replaced.
176 bool AttemptReplace(const ProtocolHandler& handler);
178 // Returns a list of protocol handlers that can be replaced by the given
179 // handler.
180 ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const;
182 // Clears the default for the provided protocol.
183 void ClearDefault(const std::string& scheme);
185 // Returns true if this handler is the default handler for its protocol.
186 bool IsDefault(const ProtocolHandler& handler) const;
188 // Initializes default protocol settings and loads them from prefs.
189 // This method must be called to complete initialization of the
190 // registry after creation, and prior to use.
191 void InitProtocolSettings();
193 // Returns the offset in the list of handlers for a protocol of the default
194 // handler for that protocol.
195 int GetHandlerIndex(const std::string& scheme) const;
197 // Get the list of protocol handlers for the given scheme.
198 ProtocolHandlerList GetHandlersFor(const std::string& scheme) const;
200 // Get the list of ignored protocol handlers.
201 ProtocolHandlerList GetIgnoredHandlers();
203 // Yields a list of the protocols that have handlers registered in this
204 // registry.
205 void GetRegisteredProtocols(std::vector<std::string>* output) const;
207 // Returns true if we allow websites to register handlers for the given
208 // scheme.
209 bool CanSchemeBeOverridden(const std::string& scheme) const;
211 // Returns true if an identical protocol handler has already been registered.
212 bool IsRegistered(const ProtocolHandler& handler) const;
214 // Returns true if an identical protocol handler has already been registered
215 // by the user.
216 bool IsRegisteredByUser(const ProtocolHandler& handler);
218 // Returns true if the scheme has at least one handler that is registered by
219 // policy.
220 bool HasPolicyRegisteredHandler(const std::string& scheme);
222 // Returns true if an identical protocol handler is being ignored.
223 bool IsIgnored(const ProtocolHandler& handler) const;
225 // Returns true if an equivalent protocol handler has already been registered.
226 bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
228 // Returns true if an equivalent protocol handler is being ignored.
229 bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
231 // Causes the given protocol handler to not be ignored anymore.
232 void RemoveIgnoredHandler(const ProtocolHandler& handler);
234 // Returns true if the protocol has a default protocol handler.
235 bool IsHandledProtocol(const std::string& scheme) const;
237 // Removes the given protocol handler from the registry.
238 void RemoveHandler(const ProtocolHandler& handler);
240 // Remove the default handler for the given protocol.
241 void RemoveDefaultHandler(const std::string& scheme);
243 // Returns the default handler for this protocol, or an empty handler if none
244 // exists.
245 const ProtocolHandler& GetHandlerFor(const std::string& scheme) const;
247 // Puts this registry in the enabled state - registered protocol handlers
248 // will handle requests.
249 void Enable();
251 // Puts this registry in the disabled state - registered protocol handlers
252 // will not handle requests.
253 void Disable();
255 // This is called by the UI thread when the system is shutting down. This
256 // does finalization which must be done on the UI thread.
257 void Shutdown() override;
259 // Registers the preferences that we store registered protocol handlers in.
260 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
262 bool enabled() const { return enabled_; }
264 // Add a predefined protocol handler. This has to be called before the first
265 // load command was issued, otherwise the command will be ignored.
266 void AddPredefinedHandler(const ProtocolHandler& handler);
268 private:
269 friend class base::DeleteHelper<ProtocolHandlerRegistry>;
270 friend struct content::BrowserThread::DeleteOnThread<
271 content::BrowserThread::IO>;
273 // for access to InstallDefaultsForChromeOS
274 friend class ProtocolHandlerRegistryFactory;
276 friend class ProtocolHandlerRegistryTest;
277 friend class RegisterProtocolHandlerBrowserTest;
279 // Puts the given handler at the top of the list of handlers for its
280 // protocol.
281 void PromoteHandler(const ProtocolHandler& handler);
283 // Saves a user's registered protocol handlers.
284 void Save();
286 // Returns a pointer to the list of handlers registered for the given scheme,
287 // or NULL if there are none.
288 const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const;
290 // Install default protocol handlers for chromeos which must be done
291 // prior to calling InitProtocolSettings.
292 void InstallDefaultsForChromeOS();
294 // Makes this ProtocolHandler the default handler for its protocol.
295 void SetDefault(const ProtocolHandler& handler);
297 // Insert the given ProtocolHandler into the registry.
298 void InsertHandler(const ProtocolHandler& handler);
300 // Returns a JSON list of protocol handlers. The caller is responsible for
301 // deleting this Value.
302 base::Value* EncodeRegisteredHandlers();
304 // Returns a JSON list of ignored protocol handlers. The caller is
305 // responsible for deleting this Value.
306 base::Value* EncodeIgnoredHandlers();
308 // Sends a notification of the given type to the NotificationService.
309 void NotifyChanged();
311 // Registers a new protocol handler.
312 void RegisterProtocolHandler(const ProtocolHandler& handler,
313 const HandlerSource source);
315 // Registers protocol handlers from the preference.
316 void RegisterProtocolHandlersFromPref(const char* pref_name,
317 const HandlerSource source);
319 // Get the DictionaryValues stored under the given pref name that are valid
320 // ProtocolHandler values.
321 std::vector<const base::DictionaryValue*> GetHandlersFromPref(
322 const char* pref_name) const;
324 // Ignores future requests to register the given protocol handler.
325 void IgnoreProtocolHandler(const ProtocolHandler& handler,
326 const HandlerSource source);
328 // Ignores protocol handlers from the preference.
329 void IgnoreProtocolHandlersFromPref(const char* pref_name,
330 const HandlerSource source);
332 // Verifies if the handler exists in the map.
333 bool HandlerExists(const ProtocolHandler& handler,
334 ProtocolHandlerMultiMap* map);
336 // Verifies if the handler exists in the list.
337 bool HandlerExists(const ProtocolHandler& handler,
338 const ProtocolHandlerList& list);
340 // Erases the handler that is guaranteed to exist from the map.
341 void EraseHandler(const ProtocolHandler& handler,
342 ProtocolHandlerMultiMap* map);
344 // Erases the handler that is guaranteed to exist from the list.
345 void EraseHandler(const ProtocolHandler& handler, ProtocolHandlerList* list);
347 // Map from protocols (strings) to protocol handlers.
348 ProtocolHandlerMultiMap protocol_handlers_;
350 // Protocol handlers that the user has told us to ignore.
351 ProtocolHandlerList ignored_protocol_handlers_;
353 // These maps track the source of protocol handler registrations for the
354 // purposes of disallowing the removal of handlers that are registered by
355 // policy. Every entry in protocol_handlers_ should exist in at least one of
356 // the user or policy maps.
357 ProtocolHandlerMultiMap user_protocol_handlers_;
358 ProtocolHandlerMultiMap policy_protocol_handlers_;
360 // These lists track the source of protocol handlers that were ignored, for
361 // the purposes of disallowing the removal of handlers that are ignored by
362 // policy. Every entry in ignored_protocol_handlers_ should exist in at least
363 // one of the user or policy lists.
364 ProtocolHandlerList user_ignored_protocol_handlers_;
365 ProtocolHandlerList policy_ignored_protocol_handlers_;
367 // Protocol handlers that are the defaults for a given protocol.
368 ProtocolHandlerMap default_handlers_;
370 // The browser context that owns this ProtocolHandlerRegistry.
371 content::BrowserContext* context_;
373 // The Delegate that registers / deregisters external handlers on our behalf.
374 scoped_ptr<Delegate> delegate_;
376 // If false then registered protocol handlers will not be used to handle
377 // requests.
378 bool enabled_;
380 // Whether or not we are loading.
381 bool is_loading_;
383 // When the table gets loaded this flag will be set and any further calls to
384 // AddPredefinedHandler will be rejected.
385 bool is_loaded_;
387 // Copy of registry data for use on the IO thread. Changes to the registry
388 // are posted to the IO thread where updates are applied to this object.
389 scoped_refptr<IOThreadDelegate> io_thread_delegate_;
391 DefaultClientObserverList default_client_observers_;
393 DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
395 #endif // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_