11a309f77SMatt Spinler #pragma once
21a309f77SMatt Spinler 
3*15c60e2fSDelphine CC Chiu #include "config.hpp"
41a309f77SMatt Spinler #include "power_button_profile.hpp"
51a309f77SMatt Spinler 
61a309f77SMatt Spinler #include <memory>
71a309f77SMatt Spinler #include <unordered_map>
81a309f77SMatt Spinler 
91a309f77SMatt Spinler namespace phosphor::button
101a309f77SMatt Spinler {
111a309f77SMatt Spinler 
121a309f77SMatt Spinler using powerButtonProfileCreator =
131a309f77SMatt Spinler     std::function<std::unique_ptr<PowerButtonProfile>(sdbusplus::bus_t& bus)>;
141a309f77SMatt Spinler 
151a309f77SMatt Spinler /**
161a309f77SMatt Spinler  * @class PowerButtonProfileFactory
171a309f77SMatt Spinler  *
181a309f77SMatt Spinler  * Creates the custom power button profile class if one is set with
191a309f77SMatt Spinler  * the 'power-button-profile' meson option.
201a309f77SMatt Spinler  *
211a309f77SMatt Spinler  * The createProfile() method will return a nullptr if no custom
221a309f77SMatt Spinler  * profile is enabled.
231a309f77SMatt Spinler  */
241a309f77SMatt Spinler class PowerButtonProfileFactory
251a309f77SMatt Spinler {
261a309f77SMatt Spinler   public:
instance()271a309f77SMatt Spinler     static PowerButtonProfileFactory& instance()
281a309f77SMatt Spinler     {
291a309f77SMatt Spinler         static PowerButtonProfileFactory factory;
301a309f77SMatt Spinler         return factory;
311a309f77SMatt Spinler     }
321a309f77SMatt Spinler 
331a309f77SMatt Spinler     template <typename T>
addToRegistry()341a309f77SMatt Spinler     void addToRegistry()
351a309f77SMatt Spinler     {
361a309f77SMatt Spinler         profileRegistry[std::string(T::getName())] = [](sdbusplus::bus_t& bus) {
371a309f77SMatt Spinler             return std::make_unique<T>(bus);
381a309f77SMatt Spinler         };
391a309f77SMatt Spinler     }
401a309f77SMatt Spinler 
createProfile(sdbusplus::bus_t & bus)411a309f77SMatt Spinler     std::unique_ptr<PowerButtonProfile> createProfile(sdbusplus::bus_t& bus)
421a309f77SMatt Spinler     {
431a309f77SMatt Spinler         // Find the creator method named after the
441a309f77SMatt Spinler         // 'power-button-profile' option value.
451a309f77SMatt Spinler         auto objectIter = profileRegistry.find(POWER_BUTTON_PROFILE);
461a309f77SMatt Spinler         if (objectIter != profileRegistry.end())
471a309f77SMatt Spinler         {
481a309f77SMatt Spinler             return objectIter->second(bus);
491a309f77SMatt Spinler         }
501a309f77SMatt Spinler         else
511a309f77SMatt Spinler         {
521a309f77SMatt Spinler             return nullptr;
531a309f77SMatt Spinler         }
541a309f77SMatt Spinler     }
551a309f77SMatt Spinler 
561a309f77SMatt Spinler   private:
571a309f77SMatt Spinler     PowerButtonProfileFactory() = default;
581a309f77SMatt Spinler 
591a309f77SMatt Spinler     std::unordered_map<std::string, powerButtonProfileCreator> profileRegistry;
601a309f77SMatt Spinler };
611a309f77SMatt Spinler 
621a309f77SMatt Spinler /**
631a309f77SMatt Spinler  * @brief Registers a power button profile with the factory.
641a309f77SMatt Spinler  *
651a309f77SMatt Spinler  * Declare a static instance of this at the top of the profile
661a309f77SMatt Spinler  * .cpp file like:
671a309f77SMatt Spinler  *    static PowerButtonProfileRegister<MyClass> register;
681a309f77SMatt Spinler  */
691a309f77SMatt Spinler template <class T>
701a309f77SMatt Spinler class PowerButtonProfileRegister
711a309f77SMatt Spinler {
721a309f77SMatt Spinler   public:
PowerButtonProfileRegister()731a309f77SMatt Spinler     PowerButtonProfileRegister()
741a309f77SMatt Spinler     {
751a309f77SMatt Spinler         PowerButtonProfileFactory::instance().addToRegistry<T>();
761a309f77SMatt Spinler     }
771a309f77SMatt Spinler };
781a309f77SMatt Spinler } // namespace phosphor::button
79