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(Profile* profile, 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 is being ignored.
    205   bool IsIgnored(const ProtocolHandler& handler) const;
    206 
    207   // Returns true if an equivalent protocol handler has already been registered.
    208   bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
    209 
    210   // Returns true if an equivalent protocol handler is being ignored.
    211   bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
    212 
    213   // Causes the given protocol handler to not be ignored anymore.
    214   void RemoveIgnoredHandler(const ProtocolHandler& handler);
    215 
    216   // Returns true if the protocol has a default protocol handler.
    217   bool IsHandledProtocol(const std::string& scheme) const;
    218 
    219   // Removes the given protocol handler from the registry.
    220   void RemoveHandler(const ProtocolHandler& handler);
    221 
    222   // Remove the default handler for the given protocol.
    223   void RemoveDefaultHandler(const std::string& scheme);
    224 
    225   // Returns the default handler for this protocol, or an empty handler if none
    226   // exists.
    227   const ProtocolHandler& GetHandlerFor(const std::string& scheme) const;
    228 
    229   // Puts this registry in the enabled state - registered protocol handlers
    230   // will handle requests.
    231   void Enable();
    232 
    233   // Puts this registry in the disabled state - registered protocol handlers
    234   // will not handle requests.
    235   void Disable();
    236 
    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;
    240 
    241   // Registers the preferences that we store registered protocol handlers in.
    242   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
    243 
    244   bool enabled() const { return enabled_; }
    245 
    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);
    249 
    250  private:
    251   friend class base::DeleteHelper<ProtocolHandlerRegistry>;
    252   friend struct content::BrowserThread::DeleteOnThread<
    253       content::BrowserThread::IO>;
    254 
    255   // for access to InstallDefaultsForChromeOS
    256   friend class ProtocolHandlerRegistryFactory;
    257 
    258   friend class ProtocolHandlerRegistryTest;
    259   friend class RegisterProtocolHandlerBrowserTest;
    260 
    261   // Puts the given handler at the top of the list of handlers for its
    262   // protocol.
    263   void PromoteHandler(const ProtocolHandler& handler);
    264 
    265   // Saves a user's registered protocol handlers.
    266   void Save();
    267 
    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;
    271 
    272   // Install default protocol handlers for chromeos which must be done
    273   // prior to calling InitProtocolSettings.
    274   void InstallDefaultsForChromeOS();
    275 
    276   // Makes this ProtocolHandler the default handler for its protocol.
    277   void SetDefault(const ProtocolHandler& handler);
    278 
    279   // Insert the given ProtocolHandler into the registry.
    280   void InsertHandler(const ProtocolHandler& handler);
    281 
    282   // Returns a JSON list of protocol handlers. The caller is responsible for
    283   // deleting this Value.
    284   base::Value* EncodeRegisteredHandlers();
    285 
    286   // Returns a JSON list of ignored protocol handlers. The caller is
    287   // responsible for deleting this Value.
    288   base::Value* EncodeIgnoredHandlers();
    289 
    290   // Sends a notification of the given type to the NotificationService.
    291   void NotifyChanged();
    292 
    293   // Registers a new protocol handler.
    294   void RegisterProtocolHandler(const ProtocolHandler& handler,
    295                                const HandlerSource source);
    296 
    297   // Registers protocol handlers from the preference.
    298   void RegisterProtocolHandlersFromPref(const char* pref_name,
    299                                         const HandlerSource source);
    300 
    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;
    305 
    306   // Ignores future requests to register the given protocol handler.
    307   void IgnoreProtocolHandler(const ProtocolHandler& handler,
    308                              const HandlerSource source);
    309 
    310   // Ignores protocol handlers from the preference.
    311   void IgnoreProtocolHandlersFromPref(const char* pref_name,
    312                                       const HandlerSource source);
    313 
    314   // Verifies if the handler exists in the map.
    315   bool HandlerExists(const ProtocolHandler& handler,
    316                      ProtocolHandlerMultiMap* map);
    317 
    318   // Verifies if the handler exists in the list.
    319   bool HandlerExists(const ProtocolHandler& handler,
    320                      const ProtocolHandlerList& list);
    321 
    322   // Erases the handler that is guaranteed to exist from the map.
    323   void EraseHandler(const ProtocolHandler& handler,
    324                     ProtocolHandlerMultiMap* map);
    325 
    326   // Erases the handler that is guaranteed to exist from the list.
    327   void EraseHandler(const ProtocolHandler& handler, ProtocolHandlerList* list);
    328 
    329   // Map from protocols (strings) to protocol handlers.
    330   ProtocolHandlerMultiMap protocol_handlers_;
    331 
    332   // Protocol handlers that the user has told us to ignore.
    333   ProtocolHandlerList ignored_protocol_handlers_;
    334 
    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_;
    341 
    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_;
    348 
    349   // Protocol handlers that are the defaults for a given protocol.
    350   ProtocolHandlerMap default_handlers_;
    351 
    352   // The Profile that owns this ProtocolHandlerRegistry.
    353   Profile* profile_;
    354 
    355   // The Delegate that registers / deregisters external handlers on our behalf.
    356   scoped_ptr<Delegate> delegate_;
    357 
    358   // If false then registered protocol handlers will not be used to handle
    359   // requests.
    360   bool enabled_;
    361 
    362   // Whether or not we are loading.
    363   bool is_loading_;
    364 
    365   // When the table gets loaded this flag will be set and any further calls to
    366   // AddPredefinedHandler will be rejected.
    367   bool is_loaded_;
    368 
    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_;
    372 
    373   DefaultClientObserverList default_client_observers_;
    374 
    375   DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
    376 };
    377 #endif  // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
    378