diff --git a/manager.cpp b/manager.cpp
new file mode 100644
index 0000000..c4732f4
--- /dev/null
+++ b/manager.cpp
@@ -0,0 +1,179 @@
+#include "manager.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace rules = sdbusplus::bus::match::rules;
+
+namespace // anonymous
+{
+constexpr auto SETTINGS_SERVICE = "org.openbmc.settings.Host";
+constexpr auto SETTINGS_PATH = "/org/openbmc/settings/host0";
+constexpr auto SETTINGS_INTERFACE = "org.openbmc.settings.Host";
+constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
+constexpr auto METHOD_GET = "Get";
+
+constexpr auto PROPERTY_TIME_MODE = "time_mode";
+constexpr auto PROPERTY_TIME_OWNER = "time_owner";
+
+// TODO: Use new settings in xyz.openbmc_project
+const auto MATCH_PROPERTY_CHANGE =
+    rules::type::signal() +
+    rules::member("PropertiesChanged") +
+    rules::path("/org/openbmc/settings/host0") +
+    rules::interface("org.freedesktop.DBus.Properties");
+
+}
+
+namespace phosphor
+{
+namespace time
+{
+
+using namespace phosphor::logging;
+
+const std::set<std::string>
+Manager::managedProperties = {PROPERTY_TIME_MODE, PROPERTY_TIME_OWNER};
+
+const std::map<std::string, Owner> Manager::ownerMap =
+{
+    { "BMC", Owner::BMC },
+    { "HOST", Owner::HOST },
+    { "SPLIT", Owner::SPLIT },
+    { "BOTH", Owner::BOTH },
+};
+
+Manager::Manager(sdbusplus::bus::bus& bus)
+    : bus(bus),
+      propertyChangeMatch(bus, MATCH_PROPERTY_CHANGE, onPropertyChanged, this)
+{
+    setCurrentTimeMode(getSettings(PROPERTY_TIME_MODE));
+    setCurrentTimeOwner(getSettings(PROPERTY_TIME_OWNER));
+}
+
+void Manager::addListener(PropertyChangeListner* listener)
+{
+    // Notify listener about the initial value
+    listener->onModeChanged(timeMode);
+    listener->onOwnerChanged(timeOwner);
+
+    listeners.insert(listener);
+}
+
+void Manager::onPropertyChanged(const std::string& key,
+                                const std::string& value)
+{
+    // TODO: Check pgood
+    // If it's off, notify listners;
+    // If it's on, hold the values and store in persistent storage.
+    // And when pgood turns back to off, notify the listners.
+
+    // TODO: Check dhcp_ntp
+
+    if (key == PROPERTY_TIME_MODE)
+    {
+        setCurrentTimeMode(value);
+        for (const auto& listener : listeners)
+        {
+            listener->onModeChanged(timeMode);
+        }
+    }
+    else if (key == PROPERTY_TIME_OWNER)
+    {
+        setCurrentTimeOwner(value);
+        for (const auto& listener : listeners)
+        {
+            listener->onOwnerChanged(timeOwner);
+        }
+    }
+}
+
+int Manager::onPropertyChanged(sd_bus_message* msg,
+                               void* userData,
+                               sd_bus_error* retError)
+{
+    using properties = std::map < std::string,
+          sdbusplus::message::variant<int, std::string >>;
+    auto m = sdbusplus::message::message(msg);
+    // message type: sa{sv}as
+    std::string ignore;
+    properties props;
+    m.read(ignore, props);
+    for (const auto& item : props)
+    {
+        if (managedProperties.find(item.first) != managedProperties.end())
+        {
+            static_cast<Manager*>(userData)
+                ->onPropertyChanged(item.first, item.second.get<std::string>());
+        }
+    }
+    return 0;
+}
+
+
+void Manager::setCurrentTimeMode(const std::string& mode)
+{
+    log<level::INFO>("Time mode is changed",
+                     entry("MODE=%s", mode.c_str()));
+    timeMode = convertToMode(mode);
+}
+
+void Manager::setCurrentTimeOwner(const std::string& owner)
+{
+    log<level::INFO>("Time owner is changed",
+                     entry("OWNER=%s", owner.c_str()));
+    timeOwner = convertToOwner(owner);
+}
+
+std::string Manager::getSettings(const char* value) const
+{
+    sdbusplus::message::variant<std::string> mode;
+    auto method = bus.new_method_call(SETTINGS_SERVICE,
+                                      SETTINGS_PATH,
+                                      PROPERTY_INTERFACE,
+                                      METHOD_GET);
+    method.append(SETTINGS_INTERFACE, value);
+    auto reply = bus.call(method);
+    if (reply)
+    {
+        reply.read(mode);
+    }
+    else
+    {
+        log<level::ERR>("Failed to get settings");
+    }
+
+    return mode.get<std::string>();
+}
+
+Mode Manager::convertToMode(const std::string& mode)
+{
+    if (mode == "NTP")
+    {
+        return Mode::NTP;
+    }
+    else if (mode == "MANUAL")
+    {
+        return Mode::MANUAL;
+    }
+    else
+    {
+        log<level::ERR>("Unrecognized mode",
+                        entry("%s", mode.c_str()));
+        return Mode::NTP;
+    }
+}
+
+Owner Manager::convertToOwner(const std::string& owner)
+{
+    auto it = ownerMap.find(owner);
+    if (it == ownerMap.end())
+    {
+        log<level::ERR>("Unrecognized owner",
+                        entry("%s", owner.c_str()));
+        return Owner::BMC;
+    }
+    return it->second;
+}
+
+}
+}
