protocol_handler_registry.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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. #ifndef COMPONENTS_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
  5. #define COMPONENTS_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/observer_list.h"
  13. #include "base/task/sequenced_task_runner_helpers.h"
  14. #include "base/time/time.h"
  15. #include "base/values.h"
  16. #include "components/keyed_service/core/keyed_service.h"
  17. #include "content/public/browser/browser_thread.h"
  18. namespace user_prefs {
  19. class PrefRegistrySyncable;
  20. }
  21. class PrefService;
  22. class GURL;
  23. using DefaultClientCallback = base::OnceCallback<void(bool)>;
  24. namespace custom_handlers {
  25. class ProtocolHandler;
  26. // This is where handlers for protocols registered with
  27. // navigator.registerProtocolHandler() are registered. Each Profile owns an
  28. // instance of this class, which is initialized on browser start through
  29. // Profile::InitRegisteredProtocolHandlers(), and they should be the only
  30. // instances of this class.
  31. class ProtocolHandlerRegistry : public KeyedService {
  32. public:
  33. enum HandlerSource {
  34. USER, // The handler was installed by user
  35. POLICY, // The handler was installed by policy
  36. };
  37. typedef std::map<std::string, ProtocolHandler, std::less<>>
  38. ProtocolHandlerMap;
  39. typedef std::vector<ProtocolHandler> ProtocolHandlerList;
  40. typedef std::map<std::string, ProtocolHandlerList, std::less<>>
  41. ProtocolHandlerMultiMap;
  42. // |Delegate| provides an interface for interacting asynchronously
  43. // with the underlying OS for the purposes of registering Chrome
  44. // as the default handler for specific protocols.
  45. class Delegate {
  46. public:
  47. virtual ~Delegate() = default;
  48. virtual void RegisterExternalHandler(const std::string& protocol) = 0;
  49. virtual bool IsExternalHandlerRegistered(const std::string& protocol) = 0;
  50. virtual void RegisterWithOSAsDefaultClient(
  51. const std::string& protocol,
  52. DefaultClientCallback callback) = 0;
  53. virtual void CheckDefaultClientWithOS(const std::string& protocol,
  54. DefaultClientCallback callback) = 0;
  55. virtual bool ShouldRemoveHandlersNotInOS() = 0;
  56. // Only implemented by TestProtocolHandlerRegistryDelegate and FakeDelegate,
  57. // hence only used for testing purposes.
  58. virtual void DeregisterExternalHandler(const std::string& protocol) {}
  59. };
  60. class Observer : public base::CheckedObserver {
  61. public:
  62. virtual void OnProtocolHandlerRegistryChanged() = 0;
  63. };
  64. // Intended for testing use only.
  65. ProtocolHandlerRegistry(PrefService* prefs,
  66. std::unique_ptr<Delegate> delegate);
  67. // Creates a new instance and performs initialization.
  68. static std::unique_ptr<ProtocolHandlerRegistry> Create(
  69. PrefService* prefs,
  70. std::unique_ptr<Delegate> delegate);
  71. ProtocolHandlerRegistry(const ProtocolHandlerRegistry&) = delete;
  72. ProtocolHandlerRegistry& operator=(const ProtocolHandlerRegistry&) = delete;
  73. ~ProtocolHandlerRegistry() override;
  74. void AddObserver(Observer* observer);
  75. void RemoveObserver(Observer* observer);
  76. // Called when a site tries to register as a protocol handler. If the request
  77. // can be handled silently by the registry - either to ignore the request
  78. // or to update an existing handler - the request will succeed. If this
  79. // function returns false the user needs to be prompted for confirmation.
  80. bool SilentlyHandleRegisterHandlerRequest(const ProtocolHandler& handler);
  81. // Called when the user accepts the registration of a given protocol handler.
  82. void OnAcceptRegisterProtocolHandler(const ProtocolHandler& handler);
  83. // Called when the user denies the registration of a given protocol handler.
  84. void OnDenyRegisterProtocolHandler(const ProtocolHandler& handler);
  85. // Called when the user indicates that they don't want to be asked about the
  86. // given protocol handler again.
  87. void OnIgnoreRegisterProtocolHandler(const ProtocolHandler& handler);
  88. // Removes all handlers that have the same origin and protocol as the given
  89. // one and installs the given handler. Returns true if any protocol handlers
  90. // were replaced.
  91. bool AttemptReplace(const ProtocolHandler& handler);
  92. // Returns a list of protocol handlers that can be replaced by the given
  93. // handler.
  94. ProtocolHandlerList GetReplacedHandlers(const ProtocolHandler& handler) const;
  95. // Clears the default for the provided protocol.
  96. void ClearDefault(const std::string& scheme);
  97. // Returns true if this handler is the default handler for its protocol.
  98. bool IsDefault(const ProtocolHandler& handler) const;
  99. // Initializes default protocol settings and loads them from prefs.
  100. // This method must be called to complete initialization of the
  101. // registry after creation, and prior to use.
  102. void InitProtocolSettings();
  103. // Returns the offset in the list of handlers for a protocol of the default
  104. // handler for that protocol.
  105. int GetHandlerIndex(base::StringPiece scheme) const;
  106. // Get the list of protocol handlers for the given scheme.
  107. ProtocolHandlerList GetHandlersFor(base::StringPiece scheme) const;
  108. // Get a list of protocol handlers registered in [begin, end).
  109. // Does not include predefined or policy installed handlers.
  110. ProtocolHandlerList GetUserDefinedHandlers(base::Time begin,
  111. base::Time end) const;
  112. // Clear all protocol handlers registered in [begin, end).
  113. // Does not delete predefined or policy installed handlers.
  114. void ClearUserDefinedHandlers(base::Time begin, base::Time end);
  115. // Get the list of ignored protocol handlers.
  116. ProtocolHandlerList GetIgnoredHandlers();
  117. // Yields a list of the protocols that have handlers registered in this
  118. // registry.
  119. void GetRegisteredProtocols(std::vector<std::string>* output) const;
  120. // Returns true if we allow websites to register handlers for the given
  121. // scheme.
  122. bool CanSchemeBeOverridden(base::StringPiece scheme) const;
  123. // Returns true if an identical protocol handler has already been registered.
  124. bool IsRegistered(const ProtocolHandler& handler) const;
  125. // Returns true if an identical protocol handler has already been registered
  126. // by the user.
  127. bool IsRegisteredByUser(const ProtocolHandler& handler);
  128. // Returns true if the scheme has at least one handler that is registered by
  129. // policy.
  130. bool HasPolicyRegisteredHandler(base::StringPiece scheme);
  131. // Returns true if an identical protocol handler is being ignored.
  132. bool IsIgnored(const ProtocolHandler& handler) const;
  133. // Returns true if an equivalent protocol handler has already been registered.
  134. bool HasRegisteredEquivalent(const ProtocolHandler& handler) const;
  135. // Returns true if an equivalent protocol handler is being ignored.
  136. bool HasIgnoredEquivalent(const ProtocolHandler& handler) const;
  137. // Causes the given protocol handler to not be ignored anymore.
  138. void RemoveIgnoredHandler(const ProtocolHandler& handler);
  139. // Returns true if the protocol has a default protocol handler.
  140. bool IsHandledProtocol(base::StringPiece scheme) const;
  141. // Removes the given protocol handler from the registry.
  142. void RemoveHandler(const ProtocolHandler& handler);
  143. // Remove the default handler for the given protocol.
  144. void RemoveDefaultHandler(base::StringPiece scheme);
  145. // Returns the default handler for this protocol, or an empty handler if none
  146. // exists.
  147. const ProtocolHandler& GetHandlerFor(base::StringPiece scheme) const;
  148. // Returns a translated URL if |url| is handled by a protocol handler,
  149. // otherwise it returns an empty URL.
  150. GURL Translate(const GURL& url) const;
  151. // Puts this registry in the enabled state - registered protocol handlers
  152. // will handle requests.
  153. void Enable();
  154. // Puts this registry in the disabled state - registered protocol handlers
  155. // will not handle requests.
  156. void Disable();
  157. // This is called by the UI thread when the system is shutting down. This
  158. // does finalization which must be done on the UI thread.
  159. void Shutdown() override;
  160. // Registers the preferences that we store registered protocol handlers in.
  161. static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
  162. bool enabled() const { return enabled_; }
  163. // Add a predefined protocol handler. This has to be called before the first
  164. // load command was issued, otherwise the command will be ignored.
  165. void AddPredefinedHandler(const ProtocolHandler& handler);
  166. void SetIsLoading(bool is_loading);
  167. private:
  168. friend class base::DeleteHelper<ProtocolHandlerRegistry>;
  169. friend struct content::BrowserThread::DeleteOnThread<
  170. content::BrowserThread::IO>;
  171. friend class ProtocolHandlerRegistryTest;
  172. // Install default protocol handlers for chromeos which must be done
  173. // prior to calling InitProtocolSettings.
  174. void InstallPredefinedHandlers();
  175. // Puts the given handler at the top of the list of handlers for its
  176. // protocol.
  177. void PromoteHandler(const ProtocolHandler& handler);
  178. // Saves a user's registered protocol handlers.
  179. void Save();
  180. // Returns a pointer to the list of handlers registered for the given scheme,
  181. // or NULL if there are none.
  182. const ProtocolHandlerList* GetHandlerList(base::StringPiece scheme) const;
  183. // Makes this ProtocolHandler the default handler for its protocol.
  184. void SetDefault(const ProtocolHandler& handler);
  185. // Insert the given ProtocolHandler into the registry.
  186. void InsertHandler(const ProtocolHandler& handler);
  187. // Returns a JSON list of protocol handlers. The caller is responsible for
  188. // deleting this Value.
  189. base::Value::List EncodeRegisteredHandlers();
  190. // Returns a JSON list of ignored protocol handlers. The caller is
  191. // responsible for deleting this Value.
  192. base::Value::List EncodeIgnoredHandlers();
  193. // Notifies observers of a change to the registry.
  194. void NotifyChanged();
  195. // Registers a new protocol handler.
  196. bool RegisterProtocolHandler(const ProtocolHandler& handler,
  197. const HandlerSource source);
  198. // Registers protocol handlers from the preference.
  199. void RegisterProtocolHandlersFromPref(const char* pref_name,
  200. const HandlerSource source);
  201. // Get all handlers with a timestamp in [begin,end) from |handlers|.
  202. ProtocolHandlerList GetHandlersBetween(
  203. const ProtocolHandlerMultiMap& handlers,
  204. base::Time begin,
  205. base::Time end) const;
  206. // Get all ignored handlers with a timestamp in [begin,end).
  207. ProtocolHandlerList GetUserIgnoredHandlers(base::Time begin,
  208. base::Time end) const;
  209. // Get the Dict values stored under the given pref name that are valid
  210. // ProtocolHandler values.
  211. // These pointers may be invalidated by other changes in the preferences
  212. // storage, hence they must not be stored in a way that outlives the current
  213. // stack frame.
  214. std::vector<const base::Value::Dict*> GetHandlersFromPref(
  215. const char* pref_name) const;
  216. // Ignores future requests to register the given protocol handler.
  217. void IgnoreProtocolHandler(const ProtocolHandler& handler,
  218. const HandlerSource source);
  219. // Ignores protocol handlers from the preference.
  220. void IgnoreProtocolHandlersFromPref(const char* pref_name,
  221. const HandlerSource source);
  222. // Verifies if the handler exists in the map.
  223. bool HandlerExists(const ProtocolHandler& handler,
  224. ProtocolHandlerMultiMap* map);
  225. // Verifies if the handler exists in the list.
  226. bool HandlerExists(const ProtocolHandler& handler,
  227. const ProtocolHandlerList& list);
  228. // Erases the handler that is guaranteed to exist from the map.
  229. void EraseHandler(const ProtocolHandler& handler,
  230. ProtocolHandlerMultiMap* map);
  231. // Erases the handler that is guaranteed to exist from the list.
  232. void EraseHandler(const ProtocolHandler& handler, ProtocolHandlerList* list);
  233. // Called with the default state when the default protocol client worker is
  234. // done.
  235. void OnSetAsDefaultProtocolClientFinished(const std::string& protocol,
  236. bool is_default);
  237. // Gets the callback that the delegate uses to respond to this instance after
  238. // a query on default client state.
  239. DefaultClientCallback GetDefaultWebClientCallback(
  240. const std::string& protocol);
  241. // Map from protocols (strings) to protocol handlers.
  242. ProtocolHandlerMultiMap protocol_handlers_;
  243. // Protocol handlers that the user has told us to ignore.
  244. ProtocolHandlerList ignored_protocol_handlers_;
  245. // These maps track the source of protocol handler registrations for the
  246. // purposes of disallowing the removal of handlers that are registered by
  247. // policy. Every entry in protocol_handlers_ should exist in at least one of
  248. // the user or policy maps.
  249. ProtocolHandlerMultiMap user_protocol_handlers_;
  250. ProtocolHandlerMultiMap policy_protocol_handlers_;
  251. // These lists track the source of protocol handlers that were ignored, for
  252. // the purposes of disallowing the removal of handlers that are ignored by
  253. // policy. Every entry in ignored_protocol_handlers_ should exist in at least
  254. // one of the user or policy lists.
  255. ProtocolHandlerList user_ignored_protocol_handlers_;
  256. ProtocolHandlerList policy_ignored_protocol_handlers_;
  257. // A list of handlers that were preinstalled.
  258. ProtocolHandlerList predefined_protocol_handlers_;
  259. // Protocol handlers that are the defaults for a given protocol.
  260. ProtocolHandlerMap default_handlers_;
  261. // The PrefService to store the registered handlers in the user profile (it
  262. // may be null for testing)
  263. raw_ptr<PrefService> prefs_ = nullptr;
  264. // The Delegate that registers / deregisters external handlers on our behalf.
  265. std::unique_ptr<Delegate> delegate_;
  266. // If false then registered protocol handlers will not be used to handle
  267. // requests.
  268. bool enabled_;
  269. // Whether or not we are loading.
  270. bool is_loading_;
  271. // When the table gets loaded this flag will be set and any further calls to
  272. // AddPredefinedHandler will be rejected.
  273. bool is_loaded_;
  274. base::ObserverList<Observer> observers_;
  275. // Makes it possible to invalidate the callback for the
  276. // DefaultProtocolClientWorker.
  277. base::WeakPtrFactory<ProtocolHandlerRegistry> weak_ptr_factory_{this};
  278. };
  279. } // namespace custom_handlers
  280. #endif // COMPONENTS_CUSTOM_HANDLERS_PROTOCOL_HANDLER_REGISTRY_H_