From a6526a034176b4171e56389f12d66e6ed528e6ce Mon Sep 17 00:00:00 2001 From: Kamil Lysik Date: Tue, 10 Feb 2015 17:36:20 +0100 Subject: [PATCH] [Filesystem] Basic File API native methods. This commit provides API for resolve method. List of native API: - File_stat - File_statSync - Filesystem_getWidgetPaths - FilesystemManager_fetchStorages Change-Id: Ieca7afa7c7a67025309c3b1223bf9082dd781bfb Signed-off-by: Kamil Lysik --- packaging/webapi-plugins.spec | 1 + src/filesystem/filesystem.gyp | 37 +++ src/filesystem/filesystem_instance.cc | 441 +++++++++----------------- src/filesystem/filesystem_instance.h | 28 +- src/filesystem/filesystem_manager.cc | 136 ++++++++ src/filesystem/filesystem_manager.h | 48 +++ src/filesystem/filesystem_stat.cc | 60 ++++ src/filesystem/filesystem_stat.h | 35 ++ src/filesystem/filesystem_storage.cc | 85 +++++ src/filesystem/filesystem_storage.h | 46 +++ src/filesystem/filesystem_utils.cc | 53 ++++ src/filesystem/filesystem_utils.h | 28 ++ src/tizen-wrt.gyp | 1 + 13 files changed, 692 insertions(+), 307 deletions(-) create mode 100644 src/filesystem/filesystem.gyp create mode 100644 src/filesystem/filesystem_manager.cc create mode 100644 src/filesystem/filesystem_manager.h create mode 100644 src/filesystem/filesystem_stat.cc create mode 100644 src/filesystem/filesystem_stat.h create mode 100644 src/filesystem/filesystem_storage.cc create mode 100644 src/filesystem/filesystem_storage.h create mode 100644 src/filesystem/filesystem_utils.cc create mode 100644 src/filesystem/filesystem_utils.h diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec index 460ae76b..392686c9 100755 --- a/packaging/webapi-plugins.spec +++ b/packaging/webapi-plugins.spec @@ -171,6 +171,7 @@ BuildRequires: pkgconfig(badge) BuildRequires: pkgconfig(x11) BuildRequires: pkgconfig(xrandr) BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(storage) BuildRequires: python BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-system-info) diff --git a/src/filesystem/filesystem.gyp b/src/filesystem/filesystem.gyp new file mode 100644 index 00000000..a8fcba96 --- /dev/null +++ b/src/filesystem/filesystem.gyp @@ -0,0 +1,37 @@ +{ + 'includes':[ + '../common/common.gypi', + ], + 'targets': [ + { + 'target_name': 'tizen_filesystem', + 'type': 'loadable_module', + 'variables': { + 'packages': [ + 'icu-i18n', + 'storage', + ], + }, + 'sources': [ + 'filesystem_api.js', + 'filesystem_extension.cc', + 'filesystem_extension.h', + 'filesystem_instance.cc', + 'filesystem_instance.h', + 'filesystem_manager.cc', + 'filesystem_manager.h', + 'filesystem_stat.cc', + 'filesystem_stat.h', + 'filesystem_storage.cc', + 'filesystem_storage.h', + 'filesystem_utils.cc', + 'filesystem_utils.h', + ], + 'conditions': [ + [ 'tizen == 1', { + 'variables': { 'packages': ['vconf'] }, + }], + ], + }, + ], +} diff --git a/src/filesystem/filesystem_instance.cc b/src/filesystem/filesystem_instance.cc index 51745d9b..a6aa27fa 100644 --- a/src/filesystem/filesystem_instance.cc +++ b/src/filesystem/filesystem_instance.cc @@ -9,6 +9,8 @@ #include "common/picojson.h" #include "common/logger.h" #include "common/platform_exception.h" +#include "common/task-queue.h" +#include "filesystem_manager.h" namespace extension { namespace filesystem { @@ -17,320 +19,183 @@ namespace { // The privileges that required in Filesystem API const std::string kPrivilegeFilesystem = ""; -} // namespace +} // namespace using namespace common; using namespace extension::filesystem; FilesystemInstance::FilesystemInstance() { using namespace std::placeholders; - #define REGISTER_SYNC(c,x) \ - RegisterSyncHandler(c, std::bind(&FilesystemInstance::x, this, _1, _2)); - REGISTER_SYNC("File_moveTo", FileMoveTo); - REGISTER_SYNC("FileSystemManager_listStorages", FileSystemManagerListStorages); - REGISTER_SYNC("FileSystemManager_resolve", FileSystemManagerResolve); - REGISTER_SYNC("FileSystemManager_addStorageStateChangeListener", FileSystemManagerAddStorageStateChangeListener); - REGISTER_SYNC("FileSystemManager_removeStorageStateChangeListener", FileSystemManagerRemoveStorageStateChangeListener); - REGISTER_SYNC("File_toURI", FileToURI); - REGISTER_SYNC("File_resolve", FileResolve); - REGISTER_SYNC("File_listFiles", FileListFiles); - REGISTER_SYNC("File_deleteDirectory", FileDeleteDirectory); - REGISTER_SYNC("File_openStream", FileOpenStream); - REGISTER_SYNC("File_createDirectory", FileCreateDirectory); - REGISTER_SYNC("File_createFile", FileCreateFile); - REGISTER_SYNC("File_deleteFile", FileDeleteFile); - REGISTER_SYNC("File_readAsText", FileReadAsText); - REGISTER_SYNC("File_copyTo", FileCopyTo); - REGISTER_SYNC("FileSystemManager_getStorage", FileSystemManagerGetStorage); - #undef REGISTER_SYNC -} - -FilesystemInstance::~FilesystemInstance() { -} - - -enum FilesystemCallbacks { - FileMoveToCallback, - FileSystemManagerListStoragesCallback, - FileSystemManagerResolveCallback, - FileSystemManagerAddStorageStateChangeListenerCallback, - FileSystemManagerRemoveStorageStateChangeListenerCallback, - FileToURICallback, - FileResolveCallback, - FileListFilesCallback, - FileDeleteDirectoryCallback, - FileOpenStreamCallback, - FileCreateDirectoryCallback, - FileCreateFileCallback, - FileDeleteFileCallback, - FileReadAsTextCallback, - FileCopyToCallback, - FileSystemManagerGetStorageCallback -}; - -static void ReplyAsync(FilesystemInstance* instance, FilesystemCallbacks cbfunc, - int callbackId, bool isSuccess, picojson::object& param) { - param["callbackId"] = picojson::value(static_cast(callbackId)); - param["status"] = picojson::value(isSuccess ? "success" : "error"); - - // insert result for async callback to param - - picojson::value result = picojson::value(param); - - instance->PostMessage(result.serialize().c_str()); -} - -#define CHECK_EXIST(args, name, out) \ - if (!args.contains(name)) {\ - ReportError(TypeMismatchException(name" is required argument"), out);\ - return;\ - } - - -void FilesystemInstance::FileSystemManagerResolve(const picojson::value& args, picojson::object& out) { +#define REGISTER_SYNC(c, x) \ + RegisterSyncHandler(c, std::bind(&FilesystemInstance::x, this, _1, _2)); +#define REGISTER_ASYNC(c, x) \ + RegisterHandler(c, std::bind(&FilesystemInstance::x, this, _1, _2)); + REGISTER_ASYNC("File_stat", FileStat); + REGISTER_SYNC("File_statSync", FileStatSync); + REGISTER_SYNC("Filesystem_getWidgetPaths", FilesystemGetWidgetPaths); + REGISTER_SYNC("FileSystemManager_fetchStorages", + FileSystemManagerFetchStorages); +#undef REGISTER_SYNC +#undef REGISTER_ASYNC +} + +FilesystemInstance::~FilesystemInstance() {} + +#define CHECK_EXIST(args, name, out) \ + if (!args.contains(name)) { \ + ReportError(TypeMismatchException(name " is required argument"), out); \ + return; \ + } + +void FilesystemInstance::FileStat(const picojson::value& args, + picojson::object& out) { + LoggerD("enter"); CHECK_EXIST(args, "callbackId", out) CHECK_EXIST(args, "location", out) - int callbackId = static_cast(args.get("callbackId").get()); + double callback_id = args.get("callbackId").get(); const std::string& location = args.get("location").get(); - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileSystemManagerGetStorage(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - CHECK_EXIST(args, "label", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& label = args.get("label").get(); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileSystemManagerListStorages(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callbackId = static_cast(args.get("callbackId").get()); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileSystemManagerAddStorageStateChangeListener(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callbackId = static_cast(args.get("callbackId").get()); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileSystemManagerRemoveStorageStateChangeListener(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "watchId", out) - - double watchId = args.get("watchId").get(); - - // implement it - - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileToURI(const picojson::value& args, picojson::object& out) { - - - // implement it - - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileListFiles(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callbackId = static_cast(args.get("callbackId").get()); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileOpenStream(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& encoding = args.get("encoding").get(); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileReadAsText(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& encoding = args.get("encoding").get(); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileCopyTo(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - CHECK_EXIST(args, "originFilePath", out) - CHECK_EXIST(args, "destinationFilePath", out) - CHECK_EXIST(args, "overwrite", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& originFilePath = args.get("originFilePath").get(); - const std::string& destinationFilePath = args.get("destinationFilePath").get(); - bool overwrite = args.get("overwrite").get(); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileMoveTo(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - CHECK_EXIST(args, "originFilePath", out) - CHECK_EXIST(args, "destinationFilePath", out) - CHECK_EXIST(args, "overwrite", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& originFilePath = args.get("originFilePath").get(); - const std::string& destinationFilePath = args.get("destinationFilePath").get(); - bool overwrite = args.get("overwrite").get(); - - // implement it - - // call ReplyAsync in later (Asynchronously) - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileCreateDirectory(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "dirPath", out) - - const std::string& dirPath = args.get("dirPath").get(); - - // implement it - - - // if success - // ReportSuccess(out); - // if error - // ReportError(out); -} -void FilesystemInstance::FileCreateFile(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "relativeFilePath", out) - - const std::string& relativeFilePath = args.get("relativeFilePath").get(); - - // implement it - + auto onSuccess = [this, callback_id](const FilesystemStat& data) { + LoggerD("enter"); + picojson::value response = picojson::value(picojson::object()); + picojson::object& obj = response.get(); + obj["callbackId"] = picojson::value(callback_id); + ReportSuccess(data.toJSON(), obj); + PostMessage(response.serialize().c_str()); + }; + + auto onError = [this, callback_id](FilesystemError e) { + LoggerD("enter"); + picojson::value response = picojson::value(picojson::object()); + picojson::object& obj = response.get(); + obj["callbackId"] = picojson::value(callback_id); + switch (e) { + case FilesystemError::None: + ReportError(UnknownException("PLATFORM ERROR"), obj); + break; + case FilesystemError::NotFound: + ReportError(NotFoundException("PLATFORM ERROR"), obj); + break; + case FilesystemError::Other: + ReportError(UnknownException("PLATFORM ERROR"), obj); + break; + default: + ReportError(UnknownException("PLATFORM ERROR"), obj); + break; + } + PostMessage(response.serialize().c_str()); + }; - // if success - // ReportSuccess(out); - // if error - // ReportError(out); + FilesystemManager& fsm = FilesystemManager::GetInstance(); + common::TaskQueue::GetInstance().Async(std::bind( + &FilesystemManager::StatPath, &fsm, location, onSuccess, onError)); } -void FilesystemInstance::FileResolve(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "filePath", out) - const std::string& filePath = args.get("filePath").get(); +void FilesystemInstance::FileStatSync(const picojson::value& args, + picojson::object& out) { + LoggerD("enter"); + CHECK_EXIST(args, "location", out) - // implement it + const std::string& location = args.get("location").get(); + auto onSuccess = [&](const FilesystemStat& data) { + LoggerD("enter"); + ReportSuccess(data.toJSON(), out); + }; + + auto onError = [&](FilesystemError e) { + LoggerD("enter"); + switch (e) { + case FilesystemError::None: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + case FilesystemError::NotFound: + ReportError(NotFoundException("PLATFORM ERROR"), out); + break; + case FilesystemError::Other: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + default: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + } + }; - // if success - // ReportSuccess(out); - // if error - // ReportError(out); + FilesystemManager::GetInstance().StatPath(location, onSuccess, onError); } -void FilesystemInstance::FileDeleteDirectory(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - CHECK_EXIST(args, "directoryPath", out) - CHECK_EXIST(args, "recursive", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& directoryPath = args.get("directoryPath").get(); - bool recursive = args.get("recursive").get(); - // implement it +void FilesystemInstance::FilesystemGetWidgetPaths(const picojson::value& args, + picojson::object& out) { + LoggerD("enter"); - // call ReplyAsync in later (Asynchronously) + auto onSuccess = [&](const std::map& result) { + LoggerD("enter"); + picojson::object paths; + for (const auto& entry : result) { + paths[entry.first] = picojson::value(entry.second); + } + ReportSuccess(picojson::value(paths), out); + }; + + auto onError = [&](FilesystemError e) { + LoggerD("enter"); + switch (e) { + case FilesystemError::None: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + case FilesystemError::NotFound: + ReportError(NotFoundException("PLATFORM ERROR"), out); + break; + case FilesystemError::Other: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + default: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + } + }; - // if success - // ReportSuccess(out); - // if error - // ReportError(out); + FilesystemManager::GetInstance().GetWidgetPaths(onSuccess, onError); } -void FilesystemInstance::FileDeleteFile(const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - CHECK_EXIST(args, "filePath", out) - - int callbackId = static_cast(args.get("callbackId").get()); - const std::string& filePath = args.get("filePath").get(); - // implement it +void FilesystemInstance::FileSystemManagerFetchStorages( + const picojson::value& args, + picojson::object& out) { + LoggerD("enter"); - // call ReplyAsync in later (Asynchronously) + auto onSuccess = [&](const std::vector& result) { + LoggerD("enter"); + picojson::array storages; + storages.reserve(result.size()); + for (const FilesystemStorage& storage : result) { + storages.push_back(storage.toJSON()); + } + ReportSuccess(picojson::value(storages), out); + }; + + auto onError = [&](FilesystemError e) { + LoggerD("enter"); + switch (e) { + case FilesystemError::None: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + case FilesystemError::NotFound: + ReportError(NotFoundException("PLATFORM ERROR"), out); + break; + case FilesystemError::Other: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + default: + ReportError(UnknownException("PLATFORM ERROR"), out); + break; + } + }; - // if success - // ReportSuccess(out); - // if error - // ReportError(out); + FilesystemManager::GetInstance().FetchStorages(onSuccess, onError); } - #undef CHECK_EXIST -} // namespace filesystem -} // namespace extension +} // namespace filesystem +} // namespace extension diff --git a/src/filesystem/filesystem_instance.h b/src/filesystem/filesystem_instance.h index 4308a3be..9b29cdf0 100644 --- a/src/filesystem/filesystem_instance.h +++ b/src/filesystem/filesystem_instance.h @@ -16,25 +16,15 @@ class FilesystemInstance : public common::ParsedInstance { virtual ~FilesystemInstance(); private: - void FileMoveTo(const picojson::value& args, picojson::object& out); - void FileSystemManagerListStorages(const picojson::value& args, picojson::object& out); - void FileSystemManagerResolve(const picojson::value& args, picojson::object& out); - void FileSystemManagerAddStorageStateChangeListener(const picojson::value& args, picojson::object& out); - void FileSystemManagerRemoveStorageStateChangeListener(const picojson::value& args, picojson::object& out); - void FileToURI(const picojson::value& args, picojson::object& out); - void FileResolve(const picojson::value& args, picojson::object& out); - void FileListFiles(const picojson::value& args, picojson::object& out); - void FileDeleteDirectory(const picojson::value& args, picojson::object& out); - void FileOpenStream(const picojson::value& args, picojson::object& out); - void FileCreateDirectory(const picojson::value& args, picojson::object& out); - void FileCreateFile(const picojson::value& args, picojson::object& out); - void FileDeleteFile(const picojson::value& args, picojson::object& out); - void FileReadAsText(const picojson::value& args, picojson::object& out); - void FileCopyTo(const picojson::value& args, picojson::object& out); - void FileSystemManagerGetStorage(const picojson::value& args, picojson::object& out); + void FileStat(const picojson::value& args, picojson::object& out); + void FileStatSync(const picojson::value& args, picojson::object& out); + void FilesystemGetWidgetPaths(const picojson::value& args, + picojson::object& out); + void FileSystemManagerFetchStorages(const picojson::value& args, + picojson::object& out); }; -} // namespace filesystem -} // namespace extension +} // namespace filesystem +} // namespace extension -#endif // FILESYSTEM_FILESYSTEM_INSTANCE_H_ +#endif // FILESYSTEM_FILESYSTEM_INSTANCE_H_ diff --git a/src/filesystem/filesystem_manager.cc b/src/filesystem/filesystem_manager.cc new file mode 100644 index 00000000..6b258593 --- /dev/null +++ b/src/filesystem/filesystem_manager.cc @@ -0,0 +1,136 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "filesystem_manager.h" + +#include +#include +#include +#include + +#include "common/logger.h" +#include "common/scope_exit.h" +#include "common/extension.h" + +namespace extension { +namespace filesystem { + +namespace { + +bool fetch_storages_cb(int storage_id, + storage_type_e type, + storage_state_e state, + const char* path, + void* user_data) { + LoggerD("enter"); + if (!user_data) { + LoggerE("Invalid user_data pointer!"); + return false; + } + + std::vector* result = + static_cast*>(user_data); + result->push_back(FilesystemStorage(storage_id, type, state, path)); + return true; +} +} + +void FilesystemManager::FetchStorages( + const std::function&)>& + success_cb, + const std::function& error_cb) { + std::vector result; + if (STORAGE_ERROR_NONE != + storage_foreach_device_supported(fetch_storages_cb, &result)) + error_cb(FilesystemError::Other); + success_cb(result); +} + +FilesystemManager::FilesystemManager() {} + +FilesystemManager& FilesystemManager::GetInstance() { + static FilesystemManager instance; + return instance; +} + +void FilesystemManager::StatPath( + const std::string& path, + const std::function& success_cb, + const std::function& error_cb) { + + FilesystemStat statData = FilesystemStat::getStat(path); + if (!statData.valid) { + error_cb(FilesystemError::Other); + return; + } + + success_cb(statData); +} + +static std::string getAppRoot() { + std::string appId = common::Extension::GetRuntimeVariable("app_id", 64); + app_info_h app_info; + int err = app_info_create(appId.c_str(), &app_info); + if (err != APP_MANAGER_ERROR_NONE) { + LoggerE("Can't create app info handle from appId (%s)", appId.c_str()); + return ""; + } + SCOPE_EXIT { + app_info_destroy(app_info); + }; + char* package = NULL; + err = app_info_get_package(app_info, &package); + if (err != APP_MANAGER_ERROR_NONE) { + LoggerE("Can't get package name from app info (%s)", + get_error_message(err)); + return ""; + } + SCOPE_EXIT { + if (package != NULL) + free(package); + }; + + package_info_h pkg_info; + err = package_info_create(package, &pkg_info); + if (err != PACKAGE_MANAGER_ERROR_NONE) { + LoggerE("Can't create package info handle from pkg (%s)", + get_error_message(err)); + return ""; + } + SCOPE_EXIT { + package_info_destroy(pkg_info); + }; + char* root = NULL; + package_info_get_root_path(pkg_info, &root); + if (err != PACKAGE_MANAGER_ERROR_NONE) { + LoggerE("Can't get root path from package info (%s)", + get_error_message(err)); + return ""; + } + std::string app_root_dir(root); + free(root); + + return app_root_dir; +} + +void FilesystemManager::GetWidgetPaths( + const std::function&)>& + success_cb, + const std::function& error_cb) { + LoggerD("enter"); + std::map result; + const std::string app_root = getAppRoot(); + LoggerD("App root is %s", app_root.c_str()); + if (app_root.empty()) { + error_cb(FilesystemError::Other); + return; + } + + result["wgt-package"] = app_root + "/res/wgt"; + result["wgt-private"] = app_root + "/data"; + result["wgt-private-tmp"] = app_root + "/tmp"; + success_cb(result); +} +} +} diff --git a/src/filesystem/filesystem_manager.h b/src/filesystem/filesystem_manager.h new file mode 100644 index 00000000..0d256b2b --- /dev/null +++ b/src/filesystem/filesystem_manager.h @@ -0,0 +1,48 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FILESYSTEM_FILESYSTEM_MANAGER_H +#define FILESYSTEM_FILESYSTEM_MANAGER_H + +#include +#include +#include + +#include "filesystem_stat.h" +#include "filesystem_storage.h" +#include "filesystem_utils.h" + +namespace extension { +namespace filesystem { + +enum class FilesystemError { + None, + NotFound, + Other +}; + +class FilesystemManager { + private: + FilesystemManager(); + + public: + static FilesystemManager& GetInstance(); + + void StatPath(const std::string& path, + const std::function& success_cb, + const std::function& error_cb); + + void FetchStorages(const std::function&)>& success_cb, + const std::function& error_cb); + + void GetWidgetPaths( + const std::function&)>& + success_cb, + const std::function& error_cb); +}; +} +} + +#endif // FILESYSTEM_FILESYSTEM_MANAGER_H diff --git a/src/filesystem/filesystem_stat.cc b/src/filesystem/filesystem_stat.cc new file mode 100644 index 00000000..1658889f --- /dev/null +++ b/src/filesystem/filesystem_stat.cc @@ -0,0 +1,60 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "filesystem_stat.h" + +#include +#include +#include + +namespace extension { +namespace filesystem { + +FilesystemStat::FilesystemStat() : valid(false) {} + +picojson::value FilesystemStat::toJSON() const { + picojson::value retval = picojson::value(picojson::object()); + picojson::object& obj = retval.get(); + + obj["isFile"] = picojson::value(isFile); + obj["isDirectory"] = picojson::value(isDirectory); + obj["readOnly"] = picojson::value(readOnly); + obj["ctime"] = picojson::value(static_cast(ctime)); + obj["mtime"] = picojson::value(static_cast(mtime)); + obj["size"] = picojson::value(static_cast(size)); + obj["nlink"] = picojson::value(static_cast(nlink)); + + return retval; +} + +FilesystemStat FilesystemStat::getStat(const std::string& path) { + struct stat aStatObj; + if (0 != stat(path.c_str(), &aStatObj)) { + return FilesystemStat(); + } + + FilesystemStat _result; + + _result.readOnly = true; + if (getuid() == aStatObj.st_uid && (aStatObj.st_mode & S_IWUSR) == S_IWUSR) { + _result.readOnly = false; + } else if (getgid() == aStatObj.st_gid && + (aStatObj.st_mode & S_IWGRP) == S_IWGRP) { + _result.readOnly = false; + } else if (aStatObj.st_mode & S_IWOTH == S_IWOTH) { + _result.readOnly = false; + } + + _result.isDirectory = S_ISDIR(aStatObj.st_mode); + _result.isFile = S_ISREG(aStatObj.st_mode); + _result.ctime = aStatObj.st_ctim.tv_sec; + _result.mtime = aStatObj.st_mtim.tv_sec; + _result.size = aStatObj.st_size; + _result.nlink = aStatObj.st_nlink; + + _result.valid = true; + return _result; +} +} +} diff --git a/src/filesystem/filesystem_stat.h b/src/filesystem/filesystem_stat.h new file mode 100644 index 00000000..e69c3445 --- /dev/null +++ b/src/filesystem/filesystem_stat.h @@ -0,0 +1,35 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FILESYSTEM_FILESYSTEM_STAT_H +#define FILESYSTEM_FILESYSTEM_STAT_H + +#include +#include + +namespace extension { +namespace filesystem { + +class FilesystemStat { + FilesystemStat(); + + public: + bool valid; + + bool isFile; + bool isDirectory; + bool readOnly; + uint64_t ctime; + uint64_t mtime; + size_t size; + size_t nlink; + + picojson::value toJSON() const; + + static FilesystemStat getStat(const std::string& path); +}; +} +} + +#endif // FILESYSTEM_FILESYSTEM_STAT_H diff --git a/src/filesystem/filesystem_storage.cc b/src/filesystem/filesystem_storage.cc new file mode 100644 index 00000000..f0e007da --- /dev/null +++ b/src/filesystem/filesystem_storage.cc @@ -0,0 +1,85 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "filesystem_storage.h" +#include "filesystem_utils.h" + +namespace extension { +namespace filesystem { + +namespace { + +StoragePaths fetch_paths(int id) { + StoragePaths paths; + paths.images = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_IMAGES); + paths.sounds = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_SOUNDS); + paths.videos = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_VIDEOS); + paths.camera = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_CAMERA); + paths.downloads = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_DOWNLOADS); + paths.music = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_MUSIC); + paths.documents = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_DOCUMENTS); + paths.others = + FilesystemUtils::get_storage_dir_path(id, STORAGE_DIRECTORY_OTHERS); + paths.ringtones = FilesystemUtils::get_storage_dir_path( + id, STORAGE_DIRECTORY_SYSTEM_RINGTONES); + return paths; +} + +picojson::value paths_to_json(const StoragePaths& storagePaths) { + picojson::object result; + if (!storagePaths.images.empty()) + result["images"] = picojson::value(storagePaths.images); + if (!storagePaths.sounds.empty()) + result["sounds"] = picojson::value(storagePaths.sounds); + if (!storagePaths.videos.empty()) + result["videos"] = picojson::value(storagePaths.videos); + if (!storagePaths.camera.empty()) + result["camera"] = picojson::value(storagePaths.camera); + if (!storagePaths.downloads.empty()) + result["downloads"] = picojson::value(storagePaths.downloads); + if (!storagePaths.music.empty()) + result["music"] = picojson::value(storagePaths.music); + if (!storagePaths.documents.empty()) + result["documents"] = picojson::value(storagePaths.documents); + if (!storagePaths.others.empty()) + result["others"] = picojson::value(storagePaths.others); + if (!storagePaths.ringtones.empty()) + result["ringtones"] = picojson::value(storagePaths.ringtones); + + return picojson::value(result); +} +} + +FilesystemStorage::FilesystemStorage(int storage_id_, + storage_type_e type_, + storage_state_e state_, + const char* path_) + : storage_id(storage_id_), + type(std::to_string(type_)), + state(std::to_string(state_)), + path(std::string(path_)), + name(std::to_string(type_) + std::to_string(storage_id_)), + paths(fetch_paths(storage_id)) {} + +picojson::value FilesystemStorage::toJSON() const { + picojson::value retval = picojson::value(picojson::object()); + picojson::object& obj = retval.get(); + + obj["storage_id"] = picojson::value(static_cast(storage_id)); + obj["type"] = picojson::value(type); + obj["state"] = picojson::value(state); + obj["path"] = picojson::value(path); + obj["name"] = picojson::value(name); + obj["paths"] = paths_to_json(paths); + return retval; +} +} +} diff --git a/src/filesystem/filesystem_storage.h b/src/filesystem/filesystem_storage.h new file mode 100644 index 00000000..12b1f88c --- /dev/null +++ b/src/filesystem/filesystem_storage.h @@ -0,0 +1,46 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FILESYSTEM_FILESYSTEM_STORAGE_H +#define FILESYSTEM_FILESYSTEM_STORAGE_H + +#include +#include +#include + +namespace extension { +namespace filesystem { + +struct StoragePaths { + std::string images; + std::string sounds; + std::string videos; + std::string camera; + std::string downloads; + std::string music; + std::string documents; + std::string others; + std::string ringtones; +}; + +class FilesystemStorage { + public: + FilesystemStorage(int storage_id, + storage_type_e type, + storage_state_e, + const char* path); + + int storage_id; + std::string type; + std::string state; + std::string path; + std::string name; + StoragePaths paths; + + picojson::value toJSON() const; +}; +} +} + +#endif // FILESYSTEM_FILESYSTEM_STORAGE_H diff --git a/src/filesystem/filesystem_utils.cc b/src/filesystem/filesystem_utils.cc new file mode 100644 index 00000000..c6bc60d1 --- /dev/null +++ b/src/filesystem/filesystem_utils.cc @@ -0,0 +1,53 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "filesystem_utils.h" + +#include "common/logger.h" + +namespace std { + +std::string to_string(storage_type_e type) { + LoggerD("enter"); + switch (type) { + case STORAGE_TYPE_INTERNAL: + return "INTERNAL"; + case STORAGE_TYPE_EXTERNAL: + return "EXTERNAL"; + default: + return ""; + } +} + +std::string to_string(storage_state_e state) { + LoggerD("enter"); + switch (state) { + case STORAGE_STATE_UNMOUNTABLE: + return "UNMOUNTABLE"; + case STORAGE_STATE_REMOVED: + return "REMOVED"; + case STORAGE_STATE_MOUNTED: + return "MOUNTED"; + case STORAGE_STATE_MOUNTED_READ_ONLY: + return "MOUNTED"; + default: + return ""; + } +} +} + +namespace FilesystemUtils { +std::string get_storage_dir_path(int id, storage_directory_e typeToCheck) { + int result = STORAGE_ERROR_NONE; + char* platformPath = NULL; + result = storage_get_directory(id, typeToCheck, &platformPath); + if (result != STORAGE_ERROR_NONE) { + LoggerD("Cannot retrieve path for type %i", typeToCheck); + return std::string(); + } + std::string path = std::string(platformPath); + free(platformPath); + return path; +} +} diff --git a/src/filesystem/filesystem_utils.h b/src/filesystem/filesystem_utils.h new file mode 100644 index 00000000..2c1c5948 --- /dev/null +++ b/src/filesystem/filesystem_utils.h @@ -0,0 +1,28 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FILESYSTEM_FILESYSTEM_UTILS_H +#define FILESYSTEM_FILESYSTEM_UTILS_H + +#include +#include +#include "common/picojson.h" + +namespace std { + +std::string to_string(storage_type_e); +std::string to_string(storage_state_e); +} + +namespace FilesystemUtils { + +/** + * @brief get_storage_dir_path attempts to get path from storage. + * If path cannot be retrieved then an empty string is returned. + * + */ +std::string get_storage_dir_path(int id, storage_directory_e typeToCheck); +} + +#endif // FILESYSTEM_FILESYSTEM_UTILS_H diff --git a/src/tizen-wrt.gyp b/src/tizen-wrt.gyp index 88db812e..b7c29a89 100755 --- a/src/tizen-wrt.gyp +++ b/src/tizen-wrt.gyp @@ -15,6 +15,7 @@ 'utils/utils.gyp:*', 'messageport/messageport.gyp:*', 'archive/archive.gyp:*', + 'filesystem/filesystem.gyp:*', 'exif/exif.gyp:*', 'websetting/websetting.gyp:*', 'systemsetting/systemsetting.gyp:*', -- 2.34.1