protocol_handler_registry.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner_helpers.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/shell_integration.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/custom_handlers/protocol_handler.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job_factory.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace user_prefs {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PrefRegistrySyncable;
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is where handlers for protocols registered with
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigator.registerProtocolHandler() are registered. Each Profile owns an
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instance of this class, which is initialized on browser start through
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Profile::InitRegisteredProtocolHandlers(), and they should be the only
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instances of this class.
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ProtocolHandlerRegistry : public KeyedService {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  enum HandlerSource {
4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    USER,    // The handler was installed by user
4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    POLICY,  // The handler was installed by policy
4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  };
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Provides notification of when the OS level user agent settings
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are changed.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class DefaultClientObserver
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : public ShellIntegration::DefaultWebClientObserver {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit DefaultClientObserver(ProtocolHandlerRegistry* registry);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~DefaultClientObserver();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get response from the worker regarding whether Chrome is the default
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // handler for the protocol.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void SetDefaultWebClientUIState(
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ShellIntegration::DefaultWebClientUIState state) OVERRIDE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give the observer a handle to the worker, so we can find out the protocol
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // when we're called and also tell the worker if we get deleted.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void SetWorker(ShellIntegration::DefaultProtocolClientWorker* worker);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShellIntegration::DefaultProtocolClientWorker* worker_;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool IsOwnedByWorker() OVERRIDE;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is a raw pointer, not reference counted, intentionally. In general
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // subclasses of DefaultWebClientObserver are not able to be refcounted
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // e.g. the browser options page
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProtocolHandlerRegistry* registry_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |Delegate| provides an interface for interacting asynchronously
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with the underlying OS for the purposes of registering Chrome
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as the default handler for specific protocols.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Delegate {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Delegate();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void RegisterExternalHandler(const std::string& protocol);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void DeregisterExternalHandler(const std::string& protocol);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool IsExternalHandlerRegistered(const std::string& protocol);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ShellIntegration::DefaultWebClientObserver* observer,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const std::string& protocol);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual DefaultClientObserver* CreateShellObserver(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProtocolHandlerRegistry* registry);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void RegisterWithOSAsDefaultClient(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const std::string& protocol,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProtocolHandlerRegistry* registry);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Forward declaration of the internal implementation class.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class IOThreadDelegate;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // JobInterceptorFactory intercepts URLRequestJob creation for URLRequests the
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ProtocolHandlerRegistry is registered to handle.  When no handler is
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // registered, the URLRequest is passed along to the chained
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // URLRequestJobFactory (set with |JobInterceptorFactory::Chain|).
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // JobInterceptorFactory's are created via
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |ProtocolHandlerRegistry::CreateJobInterceptorFactory|.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class JobInterceptorFactory : public net::URLRequestJobFactory {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |io_thread_delegate| is used to perform actual job creation work.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit JobInterceptorFactory(IOThreadDelegate* io_thread_delegate);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual ~JobInterceptorFactory();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |job_factory| is set as the URLRequestJobFactory where requests are
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // forwarded if JobInterceptorFactory decides to pass on them.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void Chain(scoped_ptr<net::URLRequestJobFactory> job_factory);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // URLRequestJobFactory implementation.
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::string& scheme,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::URLRequest* request,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::NetworkDelegate* network_delegate) const OVERRIDE;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual bool IsHandledURL(const GURL& url) const OVERRIDE;
121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // When JobInterceptorFactory decides to pass on particular requests,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // they're forwarded to the chained URLRequestJobFactory, |job_factory_|.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<URLRequestJobFactory> job_factory_;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |io_thread_delegate_| performs the actual job creation decisions by
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // mirroring the ProtocolHandlerRegistry on the IO thread.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<IOThreadDelegate> io_thread_delegate_;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(JobInterceptorFactory);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<ProtocolHandler> ProtocolHandlerList;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<DefaultClientObserver*> DefaultClientObserverList;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a new instance. Assumes ownership of |delegate|.
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ProtocolHandlerRegistry(content::BrowserContext* context, Delegate* delegate);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ProtocolHandlerRegistry();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a net::URLRequestJobFactory suitable for use on the IO thread, but
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is initialized on the UI thread.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<JobInterceptorFactory> CreateJobInterceptorFactory();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a site tries to register as a protocol handler. If the request
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // can be handled silently by the registry - either to ignore the request
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or to update an existing handler - the request will succeed. If this
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // function returns false the user needs to be prompted for confirmation.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user accepts the registration of a given protocol handler.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user denies the registration of a given protocol handler.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the user indicates that they don't want to be asked about the
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // given protocol handler again.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIgnoreRegisterProtocolHandler(const ProtocolHandler& handler);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes all handlers that have the same origin and protocol as the given
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one and installs the given handler. Returns true if any protocol handlers
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // were replaced.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AttemptReplace(const ProtocolHandler& handler);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a list of protocol handlers that can be replaced by the given
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handler.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clears the default for the provided protocol.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearDefault(const std::string& scheme);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if this handler is the default handler for its protocol.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsDefault(const ProtocolHandler& handler) const;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes default protocol settings and loads them from prefs.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method must be called to complete initialization of the
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registry after creation, and prior to use.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitProtocolSettings();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the offset in the list of handlers for a protocol of the default
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handler for that protocol.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetHandlerIndex(const std::string& scheme) const;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the list of protocol handlers for the given scheme.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProtocolHandlerList GetHandlersFor(const std::string& scheme) const;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the list of ignored protocol handlers.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProtocolHandlerList GetIgnoredHandlers();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Yields a list of the protocols that have handlers registered in this
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // registry.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetRegisteredProtocols(std::vector<std::string>* output) const;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if we allow websites to register handlers for the given
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scheme.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CanSchemeBeOverridden(const std::string& scheme) const;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if an identical protocol handler has already been registered.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsRegistered(const ProtocolHandler& handler) const;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns true if an identical protocol handler has already been registered
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // by the user.
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool IsRegisteredByUser(const ProtocolHandler& handler);
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Returns true if the scheme has at least one handler that is registered by
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // policy.
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool HasPolicyRegisteredHandler(const std::string& scheme);
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if an identical protocol handler is being ignored.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsIgnored(const ProtocolHandler& handler) const;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if an equivalent protocol handler has already been registered.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if an equivalent protocol handler is being ignored.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Causes the given protocol handler to not be ignored anymore.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveIgnoredHandler(const ProtocolHandler& handler);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the protocol has a default protocol handler.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsHandledProtocol(const std::string& scheme) const;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes the given protocol handler from the registry.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveHandler(const ProtocolHandler& handler);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the default handler for the given protocol.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveDefaultHandler(const std::string& scheme);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the default handler for this protocol, or an empty handler if none
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exists.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProtocolHandler& GetHandlerFor(const std::string& scheme) const;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Puts this registry in the enabled state - registered protocol handlers
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will handle requests.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Enable();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Puts this registry in the disabled state - registered protocol handlers
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will not handle requests.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Disable();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is called by the UI thread when the system is shutting down. This
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // does finalization which must be done on the UI thread.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Shutdown() OVERRIDE;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers the preferences that we store registered protocol handlers in.
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled() const { return enabled_; }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a predefined protocol handler. This has to be called before the first
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // load command was issued, otherwise the command will be ignored.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddPredefinedHandler(const ProtocolHandler& handler);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::DeleteHelper<ProtocolHandlerRegistry>;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct content::BrowserThread::DeleteOnThread<
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO>;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for access to InstallDefaultsForChromeOS
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ProtocolHandlerRegistryFactory;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ProtocolHandlerRegistryTest;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class RegisterProtocolHandlerBrowserTest;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Puts the given handler at the top of the list of handlers for its
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PromoteHandler(const ProtocolHandler& handler);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Saves a user's registered protocol handlers.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Save();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a pointer to the list of handlers registered for the given scheme,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or NULL if there are none.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Install default protocol handlers for chromeos which must be done
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prior to calling InitProtocolSettings.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InstallDefaultsForChromeOS();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes this ProtocolHandler the default handler for its protocol.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetDefault(const ProtocolHandler& handler);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Insert the given ProtocolHandler into the registry.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InsertHandler(const ProtocolHandler& handler);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a JSON list of protocol handlers. The caller is responsible for
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deleting this Value.
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Value* EncodeRegisteredHandlers();
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a JSON list of ignored protocol handlers. The caller is
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // responsible for deleting this Value.
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Value* EncodeIgnoredHandlers();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sends a notification of the given type to the NotificationService.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyChanged();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers a new protocol handler.
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RegisterProtocolHandler(const ProtocolHandler& handler,
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                               const HandlerSource source);
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Registers protocol handlers from the preference.
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RegisterProtocolHandlersFromPref(const char* pref_name,
30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                        const HandlerSource source);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the DictionaryValues stored under the given pref name that are valid
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ProtocolHandler values.
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<const base::DictionaryValue*> GetHandlersFromPref(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* pref_name) const;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignores future requests to register the given protocol handler.
31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void IgnoreProtocolHandler(const ProtocolHandler& handler,
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                             const HandlerSource source);
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Ignores protocol handlers from the preference.
31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void IgnoreProtocolHandlersFromPref(const char* pref_name,
32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                      const HandlerSource source);
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Verifies if the handler exists in the map.
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool HandlerExists(const ProtocolHandler& handler,
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     ProtocolHandlerMultiMap* map);
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Verifies if the handler exists in the list.
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool HandlerExists(const ProtocolHandler& handler,
32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     const ProtocolHandlerList& list);
32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Erases the handler that is guaranteed to exist from the map.
33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void EraseHandler(const ProtocolHandler& handler,
33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                    ProtocolHandlerMultiMap* map);
33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Erases the handler that is guaranteed to exist from the list.
33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void EraseHandler(const ProtocolHandler& handler, ProtocolHandlerList* list);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map from protocols (strings) to protocol handlers.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProtocolHandlerMultiMap protocol_handlers_;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Protocol handlers that the user has told us to ignore.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProtocolHandlerList ignored_protocol_handlers_;
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // These maps track the source of protocol handler registrations for the
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // purposes of disallowing the removal of handlers that are registered by
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // policy. Every entry in protocol_handlers_ should exist in at least one of
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // the user or policy maps.
34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ProtocolHandlerMultiMap user_protocol_handlers_;
34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ProtocolHandlerMultiMap policy_protocol_handlers_;
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // These lists track the source of protocol handlers that were ignored, for
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // the purposes of disallowing the removal of handlers that are ignored by
35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // policy. Every entry in ignored_protocol_handlers_ should exist in at least
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // one of the user or policy lists.
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ProtocolHandlerList user_ignored_protocol_handlers_;
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ProtocolHandlerList policy_ignored_protocol_handlers_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Protocol handlers that are the defaults for a given protocol.
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProtocolHandlerMap default_handlers_;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The browser context that owns this ProtocolHandlerRegistry.
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::BrowserContext* context_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Delegate that registers / deregisters external handlers on our behalf.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Delegate> delegate_;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If false then registered protocol handlers will not be used to handle
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requests.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled_;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether or not we are loading.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_loading_;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the table gets loaded this flag will be set and any further calls to
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AddPredefinedHandler will be rejected.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_loaded_;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copy of registry data for use on the IO thread. Changes to the registry
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are posted to the IO thread where updates are applied to this object.
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<IOThreadDelegate> io_thread_delegate_;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DefaultClientObserverList default_client_observers_;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
386