Unify monitor classes with common interface and factory 43/324443/4
authorChanggyu Choi <changyu.choi@samsung.com>
Wed, 14 May 2025 10:18:56 +0000 (19:18 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Mon, 26 May 2025 10:50:00 +0000 (19:50 +0900)
Create IMonitor interface for all monitor types (Path, DBus, Socket) and implement
MonitorFactory to centralize creation logic. Removes conditional branching from
Service class and improves maintainability.

Change-Id: Ib4dae04cd47c0d8ff3464e7d787a84b7d975fab4
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
src/activation_method/dbus_monitor.cc
src/activation_method/dbus_monitor.hh
src/activation_method/fd_monitor.cc
src/activation_method/fd_monitor.hh
src/activation_method/monitor_factory.cc [new file with mode: 0644]
src/activation_method/monitor_factory.hh [new file with mode: 0644]
src/activation_method/monitor_interface.hh [new file with mode: 0644]
src/activation_method/path_monitor.hh
src/service.cc
src/service.hh

index 09a990308389c64173118b672523f07b3126d4de..305c22d2a3aff23fb9bd3d1ae3e5faf8d84b4996 100644 (file)
@@ -35,9 +35,7 @@ DBusMonitor::DBusMonitor(std::string name,
 }
 
 DBusMonitor::~DBusMonitor() {
-  if (own_id_) {
-    g_bus_unown_name(own_id_);
-  }
+  if (own_id_) g_bus_unown_name(own_id_);
 }
 
 void DBusMonitor::BusAcquiredCb(GDBusConnection* connection,
@@ -51,9 +49,7 @@ void DBusMonitor::NameAppearedCb(GDBusConnection* connection,
                                  gpointer user_data) {
   _I("name appeared : %s", name);
   auto* self = static_cast<DBusMonitor*>(user_data);
-  if (self->bus_name_ == name) {
-    self->listener_->OnActivationEvent(self->name_);
-  }
+  if (self->bus_name_ == name) self->NotifyEvent();
 }
 
 void DBusMonitor::NameVanishedCb(GDBusConnection* connection,
@@ -62,4 +58,8 @@ void DBusMonitor::NameVanishedCb(GDBusConnection* connection,
   _E("name vanished : %s", name);
 }
 
+void DBusMonitor::NotifyEvent() {
+  if (listener_) listener_->OnActivationEvent(name_);
+}
+
 }  // namespace tizen_base
index b500c7ba1e2d7a2016f51044de27f93d903cf136..54b4bd80e6cdacea29521160ae4ada8f677ab18a 100644 (file)
 #include <string>
 
 #include "event_listener.hh"
+#include "monitor_interface.hh"
 
 namespace tizen_base {
 
-class DBusMonitor {
+class DBusMonitor : public IMonitor {
  public:
   DBusMonitor(std::string name, std::string bus_name, IActivationEventListener* listener);
-  ~DBusMonitor();
+  ~DBusMonitor() override;
+
+  const std::string& GetName() const override { return name_; }
 
   static void BusAcquiredCb(GDBusConnection* connection,
                             const gchar* name,
@@ -42,6 +45,9 @@ class DBusMonitor {
                              const gchar* name,
                              gpointer user_data);
 
+ protected:
+  void NotifyEvent() override;
+
  private:
   std::string name_;
   std::string bus_name_;
index 8e2e9c5e4caf82ebb84cc41fed6e781980ba426f..58ca6be66a7df05ad6681fa24113fddde489adef 100644 (file)
@@ -80,9 +80,13 @@ gboolean FdMonitor::UnixFdSourceFunc(gint fd,
   }
 
   _I("Receive event from fd(%d) name(%s)", fd, self->name_.c_str());
-  self->listener_->OnActivationEvent(self->name_);
+  self->NotifyEvent();
   self->unix_fd_source_id_ = 0;
   return G_SOURCE_REMOVE;
 }
 
+void FdMonitor::NotifyEvent() {
+  if (listener_) listener_->OnActivationEvent(name_);
+}
+
 }  // namespace tizen_base
index 9cc8f2dbea05d85ac698bca4645d7941fb12a597..833119f37028d0d05f0fe1c4de2abfd33f60e94a 100644 (file)
 #include <string>
 
 #include "event_listener.hh"
+#include "monitor_interface.hh"
 
 namespace tizen_base {
 
-class FdMonitor {
+class FdMonitor : public IMonitor {
  public:
-  FdMonitor(std::string, int fd, IActivationEventListener* listener);
+  FdMonitor(std::string name, int fd, IActivationEventListener* listener);
   FdMonitor(std::string name, std::string path, IActivationEventListener* listener);
-  ~FdMonitor();
+  ~FdMonitor() override;
+
+  const std::string& GetName() const override { return name_; }
+
   static gboolean UnixFdSourceFunc(gint fd, GIOCondition cond, gpointer data);
 
+ protected:
+  void NotifyEvent() override;
+
  private:
   guint unix_fd_source_id_ = 0;
   std::string name_;
diff --git a/src/activation_method/monitor_factory.cc b/src/activation_method/monitor_factory.cc
new file mode 100644 (file)
index 0000000..0fa57ad
--- /dev/null
@@ -0,0 +1,62 @@
+#include "monitor_factory.hh"
+
+#include <utility>
+
+#include "dbus_monitor.hh"
+#include "fd_monitor.hh"
+#include "path_monitor.hh"
+#include "../log_private.hh"
+
+namespace tizen_base {
+
+std::unique_ptr<IMonitor> MonitorFactory::CreateMonitor(
+    const std::shared_ptr<ServiceInfo>& info,
+    IActivationEventListener* listener) {
+  const auto& type = info->GetType();
+
+  if (type == "socket") {
+    const auto& socket_info = info->GetSocketInfo();
+    return CreateSocketMonitor(info->GetName(), socket_info->GetPath(), listener);
+  } else if (type == "path") {
+    const auto& path_info = info->GetPathInfo();
+    return CreatePathMonitor(info->GetName(), path_info->GetPath(),
+                            path_info->GetMode(), listener);
+  } else if (type == "dbus") {
+    const auto& dbus_info = info->GetDbusInfo();
+    return CreateDBusMonitor(info->GetName(), dbus_info->GetBusName(), listener);
+  }
+
+  _E("Unsupported service type: %s", type.c_str());
+  return nullptr;
+}
+
+std::unique_ptr<IMonitor> MonitorFactory::CreateDBusMonitor(
+    const std::string& name,
+    const std::string& bus_name,
+    IActivationEventListener* listener) {
+  return std::make_unique<DBusMonitor>(name, bus_name, listener);
+}
+
+std::unique_ptr<IMonitor> MonitorFactory::CreatePathMonitor(
+    const std::string& name,
+    const std::string& path,
+    PathInfo::Mode mode,
+    IActivationEventListener* listener) {
+  return std::make_unique<PathMonitor>(name, path, mode, listener);
+}
+
+std::unique_ptr<IMonitor> MonitorFactory::CreateSocketMonitor(
+    const std::string& name,
+    const std::string& path,
+    IActivationEventListener* listener) {
+  return std::make_unique<FdMonitor>(name, path, listener);
+}
+
+std::unique_ptr<IMonitor> MonitorFactory::CreateSocketMonitor(
+    const std::string& name,
+    int fd,
+    IActivationEventListener* listener) {
+  return std::make_unique<FdMonitor>(name, fd, listener);
+}
+
+}  // namespace tizen_base
diff --git a/src/activation_method/monitor_factory.hh b/src/activation_method/monitor_factory.hh
new file mode 100644 (file)
index 0000000..49d86d0
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ACTIVATION_METHOD_MONITOR_FACTORY_HH_
+#define ACTIVATION_METHOD_MONITOR_FACTORY_HH_
+
+#include <memory>
+#include <string>
+
+#include "monitor_interface.hh"
+#include "path_info.hh"
+#include "../service_info.hh"
+
+namespace tizen_base {
+
+/**
+ * @brief Factory class for creating various types of monitors
+ */
+class MonitorFactory {
+ public:
+  static std::unique_ptr<IMonitor> CreateMonitor(
+      const std::shared_ptr<ServiceInfo>& info,
+      IActivationEventListener* listener);
+
+  /**
+   * @brief Create a D-Bus monitor
+   *
+   * @param name The name for the monitor
+   * @param bus_name The D-Bus bus name to monitor
+   * @param listener The activation event listener
+   * @return std::unique_ptr<IMonitor> The created monitor
+   */
+  static std::unique_ptr<IMonitor> CreateDBusMonitor(
+      const std::string& name,
+      const std::string& bus_name,
+      IActivationEventListener* listener);
+
+  /**
+   * @brief Create a path monitor
+   *
+   * @param name The name for the monitor
+   * @param path The file system path to monitor
+   * @param mode The monitoring mode (Created, Modified, Deleted)
+   * @param listener The activation event listener
+   * @return std::unique_ptr<IMonitor> The created monitor
+   */
+  static std::unique_ptr<IMonitor> CreatePathMonitor(
+      const std::string& name,
+      const std::string& path,
+      PathInfo::Mode mode,
+      IActivationEventListener* listener);
+
+  /**
+   * @brief Create a socket monitor
+   *
+   * @param name The name for the monitor
+   * @param path The socket path
+   * @param listener The activation event listener
+   * @return std::unique_ptr<IMonitor> The created monitor
+   */
+  static std::unique_ptr<IMonitor> CreateSocketMonitor(
+      const std::string& name,
+      const std::string& path,
+      IActivationEventListener* listener);
+
+  /**
+   * @brief Create a socket monitor from a file descriptor
+   *
+   * @param name The name for the monitor
+   * @param fd The file descriptor to monitor
+   * @param listener The activation event listener
+   * @return std::unique_ptr<IMonitor> The created monitor
+   */
+  static std::unique_ptr<IMonitor> CreateSocketMonitor(
+      const std::string& name,
+      int fd,
+      IActivationEventListener* listener);
+};
+
+}  // namespace tizen_base
+
+#endif  // ACTIVATION_METHOD_MONITOR_FACTORY_HH_
diff --git a/src/activation_method/monitor_interface.hh b/src/activation_method/monitor_interface.hh
new file mode 100644 (file)
index 0000000..9571091
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ACTIVATION_METHOD_MONITOR_INTERFACE_HH_
+#define ACTIVATION_METHOD_MONITOR_INTERFACE_HH_
+
+#include <string>
+#include "../event_listener.hh"
+
+namespace tizen_base {
+
+/**
+ * @brief Interface for all types of activation method monitors
+ *
+ * Common interface for various monitor types like path, dbus, socket, etc.
+ */
+class IMonitor {
+ public:
+  virtual ~IMonitor() = default;
+
+  /**
+   * @brief Get the name of this monitor
+   * @return Monitor name
+   */
+  virtual const std::string& GetName() const = 0;
+
+ protected:
+  /**
+   * @brief Notify the listener of an activation event
+   */
+  virtual void NotifyEvent() = 0;
+};
+
+}  // namespace tizen_base
+
+#endif  // ACTIVATION_METHOD_MONITOR_INTERFACE_HH_
index 108cfc96966faf46ffbf9add962c13685de9886b..d94173fa1d19712d52ceefcab12720eecc5eff96 100644 (file)
 #include <string>
 
 #include "../event_listener.hh"
+#include "monitor_interface.hh"
 #include "path_info.hh"
 
 namespace tizen_base {
 
 namespace fs = std::filesystem;
 
-class PathMonitor {
+class PathMonitor : public IMonitor {
  public:
   PathMonitor(std::string name,
               std::string path,
               PathInfo::Mode mode,
               IActivationEventListener* listener);
 
-  ~PathMonitor();
+  ~PathMonitor() override;
+
+  const std::string& GetName() const override { return name_; }
+
+ protected:
+  void NotifyEvent() override;
 
  private:
   static gboolean OnFileChanged(GFileMonitor* monitor,
@@ -46,8 +52,6 @@ class PathMonitor {
                                 GFileMonitorEvent event_type,
                                 gpointer user_data);
 
-  void NotifyEvent();
-
   GFileMonitor* monitor_ = nullptr;
   GFile* dir_ = nullptr;
   std::string name_;
index c269edf102921e9801b71067e745a60af2059ab6..f6ab8f96e5c1c2ae1f1a414bc53e506bf6f96c81 100644 (file)
@@ -26,6 +26,7 @@
 #include "log_private.hh"
 #include "service_manager.hh"
 #include "watchdog/watchdog_manager.hh"
+#include "activation_method/monitor_factory.hh"
 
 namespace tizen_base {
 namespace {
@@ -269,29 +270,17 @@ void Service::StartMonitoring(IActivationEventListener* listener) {
     return;
   }
 
-  const auto& type = info_->GetType();
-  _I("type: %s", type.c_str());
-  if (type == "socket") {
-    const auto& socket_info = info_->GetSocketInfo();
-    fd_monitor_.reset(
-        new FdMonitor(info_->GetName(), socket_info->GetPath(), listener));
-  } else if (type == "path") {
-    const auto& path_info = info_->GetPathInfo();
-    path_monitor_.reset(new PathMonitor(info_->GetName(), path_info->GetPath(),
-                                        path_info->GetMode(), listener));
-  } else if (type == "dbus") {
-    const auto& dbus_info = info_->GetDbusInfo();
-    dbus_monitor_.reset(
-        new DBusMonitor(info_->GetName(), dbus_info->GetBusName(), listener));
+  monitor_ = MonitorFactory::CreateMonitor(info_, listener);
+  if (monitor_) {
+    monitoring_ = true;
+    _I("Started monitoring service: %s (type: %s)", info_->GetName().c_str(), info_->GetType().c_str());
+  } else {
+    _E("Failed to create monitor for service: %s", info_->GetName().c_str());
   }
-
-  monitoring_ = true;
 }
 
 void Service::StopMonitoring() {
-  fd_monitor_.reset();
-  path_monitor_.reset();
-  dbus_monitor_.reset();
+  monitor_.reset();
   monitoring_ = false;
 }
 
index c28ec4bb7a5abcc200fb70f2d05fe40b0ee6bce1..3c456f123dc7cf2ef17088d5e14ce7e1f65bd9ea 100644 (file)
 
 #include "event_listener.hh"
 #include "service_info.hh"
-
-#include "activation_method/dbus_monitor.hh"
-#include "activation_method/fd_monitor.hh"
-#include "activation_method/path_monitor.hh"
+#include "activation_method/monitor_interface.hh"
 
 namespace tizen_base {
 
@@ -103,9 +100,7 @@ class Service : public std::enable_shared_from_this<Service> {
   pid_t tid_ = -1;
   StateChangedCb state_changed_cb_ = nullptr;
 
-  std::unique_ptr<FdMonitor> fd_monitor_;
-  std::unique_ptr<PathMonitor> path_monitor_;
-  std::unique_ptr<DBusMonitor> dbus_monitor_;
+  std::unique_ptr<IMonitor> monitor_;
 };
 
 } // namespace tizen_base