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_; |