• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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"
26 
27 namespace user_prefs {
28 class PrefRegistrySyncable;
29 }
30 
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 {
37 
38  public:
39   enum HandlerSource {
40     USER,    // The handler was installed by user
41     POLICY,  // The handler was installed by policy
42   };
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     virtual ~DefaultClientObserver();
50 
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;
55 
56     virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE;
57 
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);
61 
62    protected:
63     ShellIntegration::DefaultProtocolClientWorker* worker_;
64 
65    private:
66     virtual bool IsOwnedByWorker() OVERRIDE;
67 
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_;
72 
73     DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver);
74   };
75 
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);
93   };
94 
95   // Forward declaration of the internal implementation class.
96   class IOThreadDelegate;
97 
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     virtual ~JobInterceptorFactory();
109 
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);
113 
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;
122 
123    private:
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_;
130 
131     DISALLOW_COPY_AND_ASSIGN(JobInterceptorFactory);
132   };
133 
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;
138 
139   // Creates a new instance. Assumes ownership of |delegate|.
140   ProtocolHandlerRegistry(content::BrowserContext* context, Delegate* delegate);
141   virtual ~ProtocolHandlerRegistry();
142 
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();
146 
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);
152 
153   // Called when the user accepts the registration of a given protocol handler.
154   void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler);
155 
156   // Called when the user denies the registration of a given protocol handler.
157   void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler);
158 
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);
162 
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
165   // were replaced.
166   bool AttemptReplace(const ProtocolHandler& handler);
167 
168   // Returns a list of protocol handlers that can be replaced by the given
169   // handler.
170   ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const;
171 
172   // Clears the default for the provided protocol.
173   void ClearDefault(const std::string& scheme);
174 
175   // Returns true if this handler is the default handler for its protocol.
176   bool IsDefault(const ProtocolHandler& handler) const;
177 
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();
182 
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;
186 
187   // Get the list of protocol handlers for the given scheme.
188   ProtocolHandlerList GetHandlersFor(const std::string& scheme) const;
189 
190   // Get the list of ignored protocol handlers.
191   ProtocolHandlerList GetIgnoredHandlers();
192 
193   // Yields a list of the protocols that have handlers registered in this
194   // registry.
195   void GetRegisteredProtocols(std::vector<std::string>* output) const;
196 
197   // Returns true if we allow websites to register handlers for the given
198   // scheme.
199   bool CanSchemeBeOverridden(const std::string& scheme) const;
200 
201   // Returns true if an identical protocol handler has already been registered.
202   bool IsRegistered(const ProtocolHandler& handler) const;
203 
204   // Returns true if an identical protocol handler has already been registered
205   // by the user.
206   bool IsRegisteredByUser(const ProtocolHandler& handler);
207 
208   // Returns true if the scheme has at least one handler that is registered by
209   // policy.
210   bool HasPolicyRegisteredHandler(const std::string& scheme);
211 
212   // Returns true if an identical protocol handler is being ignored.
213   bool IsIgnored(const ProtocolHandler& handler) const;
214 
215   // Returns true if an equivalent protocol handler has already been registered.
216   bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
217 
218   // Returns true if an equivalent protocol handler is being ignored.
219   bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
220 
221   // Causes the given protocol handler to not be ignored anymore.
222   void RemoveIgnoredHandler(const ProtocolHandler& handler);
223 
224   // Returns true if the protocol has a default protocol handler.
225   bool IsHandledProtocol(const std::string& scheme) const;
226 
227   // Removes the given protocol handler from the registry.
228   void RemoveHandler(const ProtocolHandler& handler);
229 
230   // Remove the default handler for the given protocol.
231   void RemoveDefaultHandler(const std::string& scheme);
232 
233   // Returns the default handler for this protocol, or an empty handler if none
234   // exists.
235   const ProtocolHandler& GetHandlerFor(const std::string& scheme) const;
236 
237   // Puts this registry in the enabled state - registered protocol handlers
238   // will handle requests.
239   void Enable();
240 
241   // Puts this registry in the disabled state - registered protocol handlers
242   // will not handle requests.
243   void Disable();
244 
245   // This is called by the UI thread when the system is shutting down. This
246   // does finalization which must be done on the UI thread.
247   virtual void Shutdown() OVERRIDE;
248 
249   // Registers the preferences that we store registered protocol handlers in.
250   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
251 
enabled()252   bool enabled() const { return enabled_; }
253 
254   // Add a predefined protocol handler. This has to be called before the first
255   // load command was issued, otherwise the command will be ignored.
256   void AddPredefinedHandler(const ProtocolHandler& handler);
257 
258  private:
259   friend class base::DeleteHelper<ProtocolHandlerRegistry>;
260   friend struct content::BrowserThread::DeleteOnThread<
261       content::BrowserThread::IO>;
262 
263   // for access to InstallDefaultsForChromeOS
264   friend class ProtocolHandlerRegistryFactory;
265 
266   friend class ProtocolHandlerRegistryTest;
267   friend class RegisterProtocolHandlerBrowserTest;
268 
269   // Puts the given handler at the top of the list of handlers for its
270   // protocol.
271   void PromoteHandler(const ProtocolHandler& handler);
272 
273   // Saves a user's registered protocol handlers.
274   void Save();
275 
276   // Returns a pointer to the list of handlers registered for the given scheme,
277   // or NULL if there are none.
278   const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const;
279 
280   // Install default protocol handlers for chromeos which must be done
281   // prior to calling InitProtocolSettings.
282   void InstallDefaultsForChromeOS();
283 
284   // Makes this ProtocolHandler the default handler for its protocol.
285   void SetDefault(const ProtocolHandler& handler);
286 
287   // Insert the given ProtocolHandler into the registry.
288   void InsertHandler(const ProtocolHandler& handler);
289 
290   // Returns a JSON list of protocol handlers. The caller is responsible for
291   // deleting this Value.
292   base::Value* EncodeRegisteredHandlers();
293 
294   // Returns a JSON list of ignored protocol handlers. The caller is
295   // responsible for deleting this Value.
296   base::Value* EncodeIgnoredHandlers();
297 
298   // Sends a notification of the given type to the NotificationService.
299   void NotifyChanged();
300 
301   // Registers a new protocol handler.
302   void RegisterProtocolHandler(const ProtocolHandler& handler,
303                                const HandlerSource source);
304 
305   // Registers protocol handlers from the preference.
306   void RegisterProtocolHandlersFromPref(const char* pref_name,
307                                         const HandlerSource source);
308 
309   // Get the DictionaryValues stored under the given pref name that are valid
310   // ProtocolHandler values.
311   std::vector<const base::DictionaryValue*> GetHandlersFromPref(
312       const char* pref_name) const;
313 
314   // Ignores future requests to register the given protocol handler.
315   void IgnoreProtocolHandler(const ProtocolHandler& handler,
316                              const HandlerSource source);
317 
318   // Ignores protocol handlers from the preference.
319   void IgnoreProtocolHandlersFromPref(const char* pref_name,
320                                       const HandlerSource source);
321 
322   // Verifies if the handler exists in the map.
323   bool HandlerExists(const ProtocolHandler& handler,
324                      ProtocolHandlerMultiMap* map);
325 
326   // Verifies if the handler exists in the list.
327   bool HandlerExists(const ProtocolHandler& handler,
328                      const ProtocolHandlerList& list);
329 
330   // Erases the handler that is guaranteed to exist from the map.
331   void EraseHandler(const ProtocolHandler& handler,
332                     ProtocolHandlerMultiMap* map);
333 
334   // Erases the handler that is guaranteed to exist from the list.
335   void EraseHandler(const ProtocolHandler& handler, ProtocolHandlerList* list);
336 
337   // Map from protocols (strings) to protocol handlers.
338   ProtocolHandlerMultiMap protocol_handlers_;
339 
340   // Protocol handlers that the user has told us to ignore.
341   ProtocolHandlerList ignored_protocol_handlers_;
342 
343   // These maps track the source of protocol handler registrations for the
344   // purposes of disallowing the removal of handlers that are registered by
345   // policy. Every entry in protocol_handlers_ should exist in at least one of
346   // the user or policy maps.
347   ProtocolHandlerMultiMap user_protocol_handlers_;
348   ProtocolHandlerMultiMap policy_protocol_handlers_;
349 
350   // These lists track the source of protocol handlers that were ignored, for
351   // the purposes of disallowing the removal of handlers that are ignored by
352   // policy. Every entry in ignored_protocol_handlers_ should exist in at least
353   // one of the user or policy lists.
354   ProtocolHandlerList user_ignored_protocol_handlers_;
355   ProtocolHandlerList policy_ignored_protocol_handlers_;
356 
357   // Protocol handlers that are the defaults for a given protocol.
358   ProtocolHandlerMap default_handlers_;
359 
360   // The browser context that owns this ProtocolHandlerRegistry.
361   content::BrowserContext* context_;
362 
363   // The Delegate that registers / deregisters external handlers on our behalf.
364   scoped_ptr<Delegate> delegate_;
365 
366   // If false then registered protocol handlers will not be used to handle
367   // requests.
368   bool enabled_;
369 
370   // Whether or not we are loading.
371   bool is_loading_;
372 
373   // When the table gets loaded this flag will be set and any further calls to
374   // AddPredefinedHandler will be rejected.
375   bool is_loaded_;
376 
377   // Copy of registry data for use on the IO thread. Changes to the registry
378   // are posted to the IO thread where updates are applied to this object.
379   scoped_refptr<IOThreadDelegate> io_thread_delegate_;
380 
381   DefaultClientObserverList default_client_observers_;
382 
383   DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
384 };
385 #endif  // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
386