From 83f98bb652f7df73334fcb1d6415355e779c449e Mon Sep 17 00:00:00 2001 From: Wojciech Kosowicz Date: Thu, 19 Feb 2015 16:38:00 +0100 Subject: [PATCH] [Filesystem] Listeners Change-Id: Ibfb16719ed9c0c55762169e30d8291afb84f1728 Signed-off-by: Wojciech Kosowicz --- src/filesystem/filesystem_instance.cc | 39 ++++++++++++++++ src/filesystem/filesystem_instance.h | 10 ++++- src/filesystem/filesystem_manager.cc | 64 ++++++++++++++++++++++++++- src/filesystem/filesystem_manager.h | 18 ++++++++ 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/filesystem/filesystem_instance.cc b/src/filesystem/filesystem_instance.cc index 9da40b8f..8d3dd31c 100644 --- a/src/filesystem/filesystem_instance.cc +++ b/src/filesystem/filesystem_instance.cc @@ -36,6 +36,10 @@ FilesystemInstance::FilesystemInstance() { REGISTER_ASYNC("File_readDir", ReadDir); REGISTER_ASYNC("File_rename", FileRename); REGISTER_SYNC("Filesystem_getWidgetPaths", FilesystemGetWidgetPaths); + REGISTER_SYNC("FileSystemManager_addStorageStateChangeListener", + StartListening); + REGISTER_SYNC("FileSystemManager_removeStorageStateChangeListener", + StopListening); REGISTER_SYNC("FileSystemManager_fetchStorages", FileSystemManagerFetchStorages); REGISTER_ASYNC("FileSystemManager_mkdir", FileSystemManagerMakeDirectory); @@ -45,6 +49,7 @@ FilesystemInstance::FilesystemInstance() { REGISTER_ASYNC("File_removeDirectory", RemoveDirectory); #undef REGISTER_SYNC #undef REGISTER_ASYNC + FilesystemManager::GetInstance().AddListener(this); } FilesystemInstance::~FilesystemInstance() {} @@ -204,6 +209,40 @@ void FilesystemInstance::FileSystemManagerFetchStorages( FilesystemManager::GetInstance().FetchStorages(onSuccess, onError); } +void FilesystemInstance::StartListening( + const picojson::value& args, + picojson::object& out) { + FilesystemManager::GetInstance().StartListening(); + ReportSuccess(out); +} + +void FilesystemInstance::StopListening( + const picojson::value& args, + picojson::object& out) { + FilesystemManager::GetInstance().StopListening(); + ReportSuccess(out); +} + +void FilesystemInstance::onFilesystemStateChangeSuccessCallback(const std::string& label, const std::string& state, const std::string& type) { + LoggerD("entered"); + + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + obj["label"] = picojson::value(label); + obj["type"] = picojson::value(type); + obj["state"] = picojson::value(state); + obj["listenerId"] = picojson::value("StorageStateChangeListener"); + PostMessage(event.serialize().c_str()); +} + +void FilesystemInstance::onFilesystemStateChangeErrorCallback() { + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + ReportError(UnknownException(std::string("Failed to registerd listener")), obj); + obj["listenerId"] = picojson::value("StorageStateChangeListener"); + LoggerD("Posting: %s", event.serialize().c_str()); + PostMessage(event.serialize().c_str()); +} void FilesystemInstance::FileSystemManagerMakeDirectory( const picojson::value& args, diff --git a/src/filesystem/filesystem_instance.h b/src/filesystem/filesystem_instance.h index 0b6fc86f..9f69e8d7 100644 --- a/src/filesystem/filesystem_instance.h +++ b/src/filesystem/filesystem_instance.h @@ -7,11 +7,13 @@ #include "common/extension.h" #include "filesystem_utils.h" +#include "filesystem_manager.h" namespace extension { namespace filesystem { -class FilesystemInstance : public common::ParsedInstance { +class FilesystemInstance : public common::ParsedInstance, + FilesystemStateChangeListener { public: FilesystemInstance(); virtual ~FilesystemInstance(); @@ -32,6 +34,12 @@ class FilesystemInstance : public common::ParsedInstance { void ReadDir(const picojson::value& args, picojson::object& out); void UnlinkFile(const picojson::value& args, picojson::object& out); void RemoveDirectory(const picojson::value& args, picojson::object& out); + void StartListening(const picojson::value& args, picojson::object& out); + void StopListening(const picojson::value& args, picojson::object& out); + void onFilesystemStateChangeErrorCallback(); + void onFilesystemStateChangeSuccessCallback(const std::string& label, + const std::string& state, + const std::string& type); void PrepareError(const FilesystemError& error, picojson::object& out); }; diff --git a/src/filesystem/filesystem_manager.cc b/src/filesystem/filesystem_manager.cc index b06e45b2..7af0624a 100644 --- a/src/filesystem/filesystem_manager.cc +++ b/src/filesystem/filesystem_manager.cc @@ -25,6 +25,18 @@ namespace extension { namespace filesystem { namespace { +void storage_cb(int storage_id, storage_state_e state, void* user_data) { + LoggerD("entered"); + if (user_data) { + FilesystemStateChangeListener* listener = + static_cast(user_data); + storage_type_e type; + storage_get_type(storage_id, &type); + listener->onFilesystemStateChangeSuccessCallback( + std::to_string(type) + std::to_string(storage_id), + std::to_string(state), std::to_string(type)); + } +} int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { @@ -89,10 +101,21 @@ void FilesystemManager::FetchStorages( if (STORAGE_ERROR_NONE != storage_foreach_device_supported(fetch_storages_cb, &result)) error_cb(FilesystemError::Other); + for(auto storage : result) { + ids_.insert(storage.storage_id); + } success_cb(result); } -FilesystemManager::FilesystemManager() {} +FilesystemManager::FilesystemManager() + : listener_(nullptr), is_listener_registered_(false) {} +FilesystemManager::~FilesystemManager() { + if (is_listener_registered_) { + for (auto id : ids_) { + storage_unset_state_changed_cb(id, storage_cb); + } + } +} FilesystemManager& FilesystemManager::GetInstance() { static FilesystemManager instance; @@ -288,5 +311,44 @@ void FilesystemManager::RemoveDirectory( success_cb(); return; } +void FilesystemManager::StartListening() { + LoggerD("enter"); + + if (!is_listener_registered_ && !ids_.empty()) { + int result = STORAGE_ERROR_NONE; + std::set registeredSuccessfully; + for (auto id : ids_) { + result = storage_set_state_changed_cb(id, storage_cb, (void*)listener_); + LoggerD("registered id %d", id); + if (result != STORAGE_ERROR_NONE) { + for (auto registeredId : registeredSuccessfully) { + storage_unset_state_changed_cb(registeredId, storage_cb); + LoggerD("unregistering id %d", registeredId); + } + listener_->onFilesystemStateChangeErrorCallback(); + break; + } else { + registeredSuccessfully.insert(id); + } + } + if (ids_.size() == registeredSuccessfully.size()) + is_listener_registered_ = true; + } +} + +void FilesystemManager::StopListening() { + LoggerD("enter"); + if (is_listener_registered_) { + for (auto id : ids_) { + storage_unset_state_changed_cb(id, storage_cb); + } + } + is_listener_registered_ = false; +} + +void FilesystemManager::AddListener(FilesystemStateChangeListener* listener) { + LoggerD("enter"); + listener_ = listener; +} } // namespace filesystem } // namespace extension diff --git a/src/filesystem/filesystem_manager.h b/src/filesystem/filesystem_manager.h index cffae4a5..d1d44c10 100644 --- a/src/filesystem/filesystem_manager.h +++ b/src/filesystem/filesystem_manager.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "filesystem_stat.h" #include "filesystem_storage.h" @@ -16,9 +17,19 @@ namespace extension { namespace filesystem { +class FilesystemStateChangeListener { + public: + virtual void onFilesystemStateChangeSuccessCallback( + const std::string& label, const std::string& state, + const std::string& type) = 0; + virtual void onFilesystemStateChangeErrorCallback() = 0; +}; + class FilesystemManager { private: FilesystemManager(); + ~FilesystemManager(); + FilesystemStateChangeListener* listener_; public: static FilesystemManager& GetInstance(); @@ -62,6 +73,13 @@ class FilesystemManager { const std::string& path, const std::function& success_cb, const std::function& error_cb); + void StartListening(); + void StopListening(); + void AddListener(FilesystemStateChangeListener* listener); + + bool is_listener_registered_; + static std::vector storages; + std::set ids_; }; } // namespace filesystem } // namespace extension -- 2.34.1