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);
REGISTER_ASYNC("File_removeDirectory", RemoveDirectory);
#undef REGISTER_SYNC
#undef REGISTER_ASYNC
+ FilesystemManager::GetInstance().AddListener(this);
}
FilesystemInstance::~FilesystemInstance() {}
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,
#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();
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);
};
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)
{
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;
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
#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();
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