protocol_handler_registry.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/sequenced_task_runner_helpers.h"
15#include "base/values.h"
16#include "chrome/browser/profiles/profile.h"
17#include "chrome/browser/shell_integration.h"
18#include "chrome/common/custom_handlers/protocol_handler.h"
19#include "content/public/browser/browser_thread.h"
20#include "content/public/browser/notification_service.h"
21#include "net/url_request/url_request.h"
22#include "net/url_request/url_request_job.h"
23#include "net/url_request/url_request_job_factory.h"
24
25// This is where handlers for protocols registered with
26// navigator.registerProtocolHandler() are registered. Each Profile owns an
27// instance of this class, which is initialized on browser start through
28// Profile::InitRegisteredProtocolHandlers(), and they should be the only
29// instances of this class.
30class ProtocolHandlerRegistry : public ProfileKeyedService {
31
32 public:
33  // Provides notification of when the OS level user agent settings
34  // are changed.
35  class DefaultClientObserver
36      : public ShellIntegration::DefaultWebClientObserver {
37   public:
38    explicit DefaultClientObserver(ProtocolHandlerRegistry* registry);
39    virtual ~DefaultClientObserver();
40
41    // Get response from the worker regarding whether Chrome is the default
42    // handler for the protocol.
43    virtual void SetDefaultWebClientUIState(
44        ShellIntegration::DefaultWebClientUIState state) OVERRIDE;
45
46    virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE;
47
48    // Give the observer a handle to the worker, so we can find out the protocol
49    // when we're called and also tell the worker if we get deleted.
50    void SetWorker(ShellIntegration::DefaultProtocolClientWorker* worker);
51
52   protected:
53    ShellIntegration::DefaultProtocolClientWorker* worker_;
54
55   private:
56    virtual bool IsOwnedByWorker() OVERRIDE;
57
58    // This is a raw pointer, not reference counted, intentionally. In general
59    // subclasses of DefaultWebClientObserver are not able to be refcounted
60    // e.g. the browser options page
61    ProtocolHandlerRegistry* registry_;
62
63    DISALLOW_COPY_AND_ASSIGN(DefaultClientObserver);
64  };
65
66  // |Delegate| provides an interface for interacting asynchronously
67  // with the underlying OS for the purposes of registering Chrome
68  // as the default handler for specific protocols.
69  class Delegate {
70   public:
71    virtual ~Delegate();
72    virtual void RegisterExternalHandler(const std::string& protocol);
73    virtual void DeregisterExternalHandler(const std::string& protocol);
74    virtual bool IsExternalHandlerRegistered(const std::string& protocol);
75    virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
76        ShellIntegration::DefaultWebClientObserver* observer,
77        const std::string& protocol);
78    virtual DefaultClientObserver* CreateShellObserver(
79        ProtocolHandlerRegistry* registry);
80    virtual void RegisterWithOSAsDefaultClient(
81        const std::string& protocol,
82        ProtocolHandlerRegistry* registry);
83  };
84
85  typedef std::map<std::string, ProtocolHandler> ProtocolHandlerMap;
86  typedef std::vector<ProtocolHandler> ProtocolHandlerList;
87  typedef std::map<std::string, ProtocolHandlerList> ProtocolHandlerMultiMap;
88  typedef std::vector<DefaultClientObserver*> DefaultClientObserverList;
89
90  // Creates a new instance. Assumes ownership of |delegate|.
91  ProtocolHandlerRegistry(Profile* profile, Delegate* delegate);
92  virtual ~ProtocolHandlerRegistry();
93
94  // Returns a net::URLRequestJobFactory::Interceptor suitable
95  // for use on the IO thread, but is initialized on the UI thread.
96  // Callers assume responsibility for deleting this object.
97  net::URLRequestJobFactory::Interceptor* CreateURLInterceptor();
98
99  // Called when a site tries to register as a protocol handler. If the request
100  // can be handled silently by the registry - either to ignore the request
101  // or to update an existing handler - the request will succeed. If this
102  // function returns false the user needs to be prompted for confirmation.
103  bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler);
104
105  // Called when the user accepts the registration of a given protocol handler.
106  void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler);
107
108  // Called when the user denies the registration of a given protocol handler.
109  void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler);
110
111  // Called when the user indicates that they don't want to be asked about the
112  // given protocol handler again.
113  void OnIgnoreRegisterProtocolHandler(const ProtocolHandler& handler);
114
115  // Removes all handlers that have the same origin and protocol as the given
116  // one and installs the given handler. Returns true if any protocol handlers
117  // were replaced.
118  bool AttemptReplace(const ProtocolHandler& handler);
119
120  // Returns a list of protocol handlers that can be replaced by the given
121  // handler.
122  ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const;
123
124  // Clears the default for the provided protocol.
125  void ClearDefault(const std::string& scheme);
126
127  // Returns true if this handler is the default handler for its protocol.
128  bool IsDefault(const ProtocolHandler& handler) const;
129
130  // Initializes default protocol settings and loads them from prefs.
131  // This method must be called to complete initialization of the
132  // registry after creation, and prior to use.
133  void InitProtocolSettings();
134
135  // Returns the offset in the list of handlers for a protocol of the default
136  // handler for that protocol.
137  int GetHandlerIndex(const std::string& scheme) const;
138
139  // Get the list of protocol handlers for the given scheme.
140  ProtocolHandlerList GetHandlersFor(const std::string& scheme) const;
141
142  // Get the list of ignored protocol handlers.
143  ProtocolHandlerList GetIgnoredHandlers();
144
145  // Yields a list of the protocols that have handlers registered in this
146  // registry.
147  void GetRegisteredProtocols(std::vector<std::string>* output) const;
148
149  // Returns true if we allow websites to register handlers for the given
150  // scheme.
151  bool CanSchemeBeOverridden(const std::string& scheme) const;
152
153  // Returns true if an identical protocol handler has already been registered.
154  bool IsRegistered(const ProtocolHandler& handler) const;
155
156  // Returns true if an identical protocol handler is being ignored.
157  bool IsIgnored(const ProtocolHandler& handler) const;
158
159  // Returns true if an equivalent protocol handler has already been registered.
160  bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
161
162  // Returns true if an equivalent protocol handler is being ignored.
163  bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
164
165  // Causes the given protocol handler to not be ignored anymore.
166  void RemoveIgnoredHandler(const ProtocolHandler& handler);
167
168  // Returns true if the protocol has a default protocol handler.
169  bool IsHandledProtocol(const std::string& scheme) const;
170
171  // Removes the given protocol handler from the registry.
172  void RemoveHandler(const ProtocolHandler& handler);
173
174  // Remove the default handler for the given protocol.
175  void RemoveDefaultHandler(const std::string& scheme);
176
177  // Returns the default handler for this protocol, or an empty handler if none
178  // exists.
179  const ProtocolHandler& GetHandlerFor(const std::string& scheme) const;
180
181  // Puts this registry in the enabled state - registered protocol handlers
182  // will handle requests.
183  void Enable();
184
185  // Puts this registry in the disabled state - registered protocol handlers
186  // will not handle requests.
187  void Disable();
188
189  // This is called by the UI thread when the system is shutting down. This
190  // does finalization which must be done on the UI thread.
191  virtual void Shutdown() OVERRIDE;
192
193  // Registers the preferences that we store registered protocol handlers in.
194  static void RegisterPrefs(PrefService* prefService);
195
196  bool enabled() const { return enabled_; }
197
198  // Add a predefined protocol handler. This has to be called before the first
199  // load command was issued, otherwise the command will be ignored.
200  void AddPredefinedHandler(const ProtocolHandler& handler);
201
202 private:
203  friend class base::DeleteHelper<ProtocolHandlerRegistry>;
204  friend struct content::BrowserThread::DeleteOnThread<
205      content::BrowserThread::IO>;
206
207  // for access to InstallDefaultsForChromeOS
208  friend class ProtocolHandlerRegistryFactory;
209
210  friend class ProtocolHandlerRegistryTest;
211  friend class RegisterProtocolHandlerBrowserTest;
212
213  // Forward declaration of the internal implementation classes.
214  class Core;
215  class URLInterceptor;
216
217  // Puts the given handler at the top of the list of handlers for its
218  // protocol.
219  void PromoteHandler(const ProtocolHandler& handler);
220
221  // Saves a user's registered protocol handlers.
222  void Save();
223
224  // Returns a pointer to the list of handlers registered for the given scheme,
225  // or NULL if there are none.
226  const ProtocolHandlerList* GetHandlerList(const std::string& scheme) const;
227
228  // Install default protocol handlers for chromeos which must be done
229  // prior to calling InitProtocolSettings.
230  void InstallDefaultsForChromeOS();
231
232  // Makes this ProtocolHandler the default handler for its protocol.
233  void SetDefault(const ProtocolHandler& handler);
234
235  // Insert the given ProtocolHandler into the registry.
236  void InsertHandler(const ProtocolHandler& handler);
237
238  // Returns a JSON list of protocol handlers. The caller is responsible for
239  // deleting this Value.
240  Value* EncodeRegisteredHandlers();
241
242  // Returns a JSON list of ignored protocol handlers. The caller is
243  // responsible for deleting this Value.
244  Value* EncodeIgnoredHandlers();
245
246  // Sends a notification of the given type to the NotificationService.
247  void NotifyChanged();
248
249  // Registers a new protocol handler.
250  void RegisterProtocolHandler(const ProtocolHandler& handler);
251
252  // Get the DictionaryValues stored under the given pref name that are valid
253  // ProtocolHandler values.
254  std::vector<const DictionaryValue*> GetHandlersFromPref(
255      const char* pref_name) const;
256
257  // Ignores future requests to register the given protocol handler.
258  void IgnoreProtocolHandler(const ProtocolHandler& handler);
259
260  // Map from protocols (strings) to protocol handlers.
261  ProtocolHandlerMultiMap protocol_handlers_;
262
263  // Protocol handlers that the user has told us to ignore.
264  ProtocolHandlerList ignored_protocol_handlers_;
265
266  // Protocol handlers that are the defaults for a given protocol.
267  ProtocolHandlerMap default_handlers_;
268
269  // The Profile that owns this ProtocolHandlerRegistry.
270  Profile* profile_;
271
272  // The Delegate that registers / deregisters external handlers on our behalf.
273  scoped_ptr<Delegate> delegate_;
274
275  // If false then registered protocol handlers will not be used to handle
276  // requests.
277  bool enabled_;
278
279  // Whether or not we are loading.
280  bool is_loading_;
281
282  // When the table gets loaded this flag will be set and any further calls to
283  // AddPredefinedHandler will be rejected.
284  bool is_loaded_;
285
286  // Copy of registry data for use on the IO thread. Changes to the registry
287  // are posted to the IO thread where updates are applied to this object.
288  scoped_refptr<Core> core_;
289
290  DefaultClientObserverList default_client_observers_;
291
292  DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerRegistry);
293};
294#endif  // CHROME_BROWSER_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
295