Home | History | Annotate | Download | only in custom_handlers
      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 
    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