Chromium Code Reviews| Index: components/arc/arc_service_manager.h |
| diff --git a/components/arc/arc_service_manager.h b/components/arc/arc_service_manager.h |
| index 81a4ea9e98b2e715e289b112d3cae2660d72cbd6..6a339d3ce1b9b05ef1b21b30a44e127a2d89c714 100644 |
| --- a/components/arc/arc_service_manager.h |
| +++ b/components/arc/arc_service_manager.h |
| @@ -6,6 +6,10 @@ |
| #define COMPONENTS_ARC_ARC_SERVICE_MANAGER_H_ |
| #include <memory> |
| +#include <string> |
| +#include <type_traits> |
| +#include <unordered_map> |
| +#include <utility> |
| #include <vector> |
| #include "base/macros.h" |
| @@ -22,6 +26,34 @@ class ArcBridgeService; |
| class ArcIntentHelperObserver; |
| class ArcService; |
| +namespace internal { |
| + |
| +// If an ArcService is declared with a Name, e.g.: |
|
Yusuke Sato
2017/01/10 19:30:57
s/Name/name/ is better now.
Luis Héctor Chávez
2017/01/10 23:48:09
Done.
|
| +// |
| +// class MyArcService : public ArcService { |
| +// public: |
| +// static const char kArcServiceName[]; |
| +// ... |
| +// }; |
| +// |
| +// it can then be retrieved from ArcServiceManager in a type-safe way using |
| +// GetService<T>(). This two functions allow AddService() to get the name only |
| +// if it was provided, or use an empty string otherwise. |
| +// |
| +// In order to avoid collisions, kArcServiceName should be the fully-qualified |
| +// name of the class. |
| +template <typename T> |
| +decltype(T::kArcServiceName, std::string()) GetArcServiceName(T* unused) { |
| + return T::kArcServiceName; |
|
Yusuke Sato
2017/01/10 19:30:57
LOG(ERROR) when T::kArcServiceName is an empty str
Luis Héctor Chávez
2017/01/10 23:48:09
Done.
|
| +} |
| + |
| +template <typename T> |
| +std::string GetArcServiceName(...) { |
| + return std::string(); |
| +} |
| + |
| +} // namespace internal |
| + |
| // Manages creation and destruction of services that communicate with the ARC |
| // instance via the ArcBridgeService. |
| class ArcServiceManager { |
| @@ -48,8 +80,22 @@ class ArcServiceManager { |
| // class was created on. |
| ArcBridgeService* arc_bridge_service(); |
| - // Adds a service to the managed services list. |
| - void AddService(std::unique_ptr<ArcService> service); |
| + // Adds a service to the managed services list. Returns false if another |
| + // named service with that name had already been added. |
| + template <typename T> |
| + bool AddService(std::unique_ptr<T> service) { |
| + return AddServiceInternal(internal::GetArcServiceName<T>(nullptr), |
| + std::move(service)); |
| + } |
| + |
| + // Gets the named service from the managed services list. This uses SFINAE, so |
| + // you can only call this function if the service specified by T provides a |
| + // static member variable called kArcServiceName[] (otherwise this will not |
| + // compile). |
| + template <typename T> |
| + T* GetService() { |
| + return static_cast<T*>(GetNamedServiceInternal(T::kArcServiceName)); |
| + } |
| // Gets the global instance of the ARC Service Manager. This can only be |
| // called on the thread that this class was created on. |
| @@ -81,6 +127,11 @@ class ArcServiceManager { |
| private: |
| class IntentHelperObserverImpl; // implemented in arc_service_manager.cc. |
| + // Helper methods for AddService and GetService. |
| + bool AddServiceInternal(const std::string& name, |
| + std::unique_ptr<ArcService> service); |
| + ArcService* GetNamedServiceInternal(const std::string& name); |
| + |
| base::ThreadChecker thread_checker_; |
| scoped_refptr<base::TaskRunner> blocking_task_runner_; |
| @@ -88,7 +139,7 @@ class ArcServiceManager { |
| std::unique_ptr<ArcIntentHelperObserver> intent_helper_observer_; |
| std::unique_ptr<ArcBridgeService> arc_bridge_service_; |
| - std::vector<std::unique_ptr<ArcService>> services_; |
| + std::unordered_multimap<std::string, std::unique_ptr<ArcService>> services_; |
| scoped_refptr<ActivityIconLoader> icon_loader_; |
| scoped_refptr<LocalActivityResolver> activity_resolver_; |