#include "file_monitor.hh"
-tizen_base::FileMonitor::FileMonitor(std::string name,
- std::string path,
- IEventListener* listener) {}
+#include <system_error>
-gboolean tizen_base::FileMonitor::UnixFdSourceFunc(gint fd,
- GIOCondition cond,
- gpointer data) {
- // TODO
- return FALSE;
+#include "../log_private.hh"
+
+namespace tizen_base {
+
+FileMonitor::FileMonitor(std::string name,
+ std::string path,
+ IEventListener* listener)
+ : name_(std::move(name)), listener_(listener) {
+ fs::path full_path = fs::path(path);
+ std::error_code error;
+ if (fs::exists(full_path, error)) {
+ _W("[%s] already exists", full_path.string().c_str());
+ g_idle_add(
+ +[](gpointer data) -> gboolean {
+ auto* self = static_cast<FileMonitor*>(data);
+ self->NotifyEvent();
+ return G_SOURCE_REMOVE;
+ },
+ this);
+ return;
+ }
+
+ listener_ = listener;
+ dir_path_ = full_path.parent_path();
+ file_name_ = full_path.filename().string();
+ dir_ = g_file_new_for_path(dir_path_.c_str());
+ monitor_ =
+ g_file_monitor_directory(dir_, G_FILE_MONITOR_NONE, nullptr, nullptr);
+
+ if (monitor_ == nullptr) {
+ g_object_unref(dir_);
+ dir_ = nullptr;
+ std::runtime_error("Failed to create monitor");
+ }
+
+ g_signal_connect(monitor_, "changed", G_CALLBACK(OnFileChanged), this);
+ if (fs::exists(full_path, error)) {
+ if (monitor_)
+ g_object_unref(monitor_);
+
+ if (dir_)
+ g_object_unref(dir_);
+
+ g_idle_add(
+ +[](gpointer data) -> gboolean {
+ auto* self = static_cast<FileMonitor*>(data);
+ self->NotifyEvent();
+ return G_SOURCE_REMOVE;
+ },
+ this);
+ }
+}
+
+FileMonitor::~FileMonitor() {
+ if (monitor_)
+ g_object_unref(monitor_);
+
+ if (dir_)
+ g_object_unref(dir_);
}
+
+gboolean FileMonitor::OnFileChanged(GFileMonitor* monitor,
+ GFile* file,
+ GFile* other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data) {
+ auto* self = static_cast<FileMonitor*>(user_data);
+ const auto& file_name = self->file_name_;
+ gchar* basename = g_file_get_basename(file);
+
+ if (event_type == G_FILE_MONITOR_EVENT_CREATED &&
+ strcmp(basename, file_name.c_str()) == 0) {
+ _I("[%s] created", basename);
+ self->NotifyEvent();
+
+ return G_SOURCE_REMOVE;
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+void FileMonitor::NotifyEvent() {
+ if (listener_)
+ listener_->OnEvent(name_);
+}
+
+} // namespace tizen_base
#ifndef ACTIVATION_METHOD_FILE_MONITOR_HH_
#define ACTIVATION_METHOD_FILE_MONITOR_HH_
-#include <glib.h>
#include <gio/gio.h>
+#include <glib.h>
+#include <filesystem>
#include <string>
-#include "event_listener.hh"
+#include "../event_listener.hh"
namespace tizen_base {
+namespace fs = std::filesystem;
+
class FileMonitor {
public:
FileMonitor(std::string name, std::string path, IEventListener* listener);
- static gboolean UnixFdSourceFunc(gint fd, GIOCondition cond, gpointer data);
-};
+ ~FileMonitor();
+ private:
+ static gboolean OnFileChanged(GFileMonitor* monitor,
+ GFile* file,
+ GFile* other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data);
+
+ void NotifyEvent();
+
+ GFileMonitor* monitor_ = nullptr;
+ GFile* dir_ = nullptr;
+ std::string name_;
+ fs::path dir_path_;
+ std::string file_name_;
+ IEventListener* listener_;
};
+}; // namespace tizen_base
+
#endif // ACTIVATION_METHOD_FILE_MONITOR_HH_