[Filesystem] Listeners
authorWojciech Kosowicz <w.kosowicz@samsung.com>
Thu, 19 Feb 2015 15:38:00 +0000 (16:38 +0100)
committerWojciech Kosowicz <w.kosowicz@samsung.com>
Tue, 24 Feb 2015 08:01:16 +0000 (09:01 +0100)
Change-Id: Ibfb16719ed9c0c55762169e30d8291afb84f1728
Signed-off-by: Wojciech Kosowicz <w.kosowicz@samsung.com>
src/filesystem/filesystem_instance.cc
src/filesystem/filesystem_instance.h
src/filesystem/filesystem_manager.cc
src/filesystem/filesystem_manager.h

index 9da40b8fa1eb3d8f6f89088f1d4b268db8733987..8d3dd31c716ac8a0948c76a42ee02787694e9b3b 100644 (file)
@@ -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<picojson::object>();
+  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<picojson::object>();
+  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,
index 0b6fc86fab68ddf0f3175b06b9ab11fd5c5c46c8..9f69e8d7288c27cae5912b610de2a031b92bea1c 100644 (file)
@@ -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);
 };
 
index b06e45b2e9b6c27fef469ed35eea690283ae7a02..7af0624aded9b97de7deb52a8d4ac2afdbf9e466 100644 (file)
@@ -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<FilesystemStateChangeListener*>(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<int> 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
index cffae4a59a5439064239b628a4cecac17224b654..d1d44c107e0225c484fc1ec25afa92424a534645 100644 (file)
@@ -8,6 +8,7 @@
 #include <functional>
 #include <string>
 #include <vector>
+#include <set>
 
 #include "filesystem_stat.h"
 #include "filesystem_storage.h"
 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<void()>& success_cb,
           const std::function<void(FilesystemError)>& error_cb);
+  void StartListening();
+  void StopListening();
+  void AddListener(FilesystemStateChangeListener* listener);
+
+  bool is_listener_registered_;
+  static std::vector<FilesystemStorage> storages;
+  std::set<int> ids_;
 };
 }  // namespace filesystem
 }  // namespace extension