From 3eca21c26b613b9f8330aed48edefe2133a9ffc5 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 6 Feb 2015 15:16:10 +0900 Subject: [PATCH 02/11] libstorage: Add initial libstorage code This library provides functions to get storage information. The type of stroage information includes: * root directory * storage type(internal or external) * storage status * total and available space size (without minimum memory to launch application) The type of directory information includes: * Images * Sounds * Videos * Camera * Downloads * Music * Documents * Others * System ringtones Signed-off-by: Jiyoung Yun --- CMakeLists.txt | 52 ++++++ LICENSE | 204 +++++++++++++++++++++++ doc/storage_doc.h | 51 ++++++ include/common.h | 80 +++++++++ include/list.h | 68 ++++++++ include/log.h | 57 +++++++ include/storage-expand.h | 331 +++++++++++++++++++++++++++++++++++++ include/storage.h | 120 ++++++++++++++ packaging/libstorage.manifest | 5 + packaging/libstorage.spec | 51 ++++++ src/libstorage.conf | 7 + src/statvfs.c | 374 ++++++++++++++++++++++++++++++++++++++++++ src/storage-internal.c | 73 +++++++++ src/storage-sdcard.c | 218 ++++++++++++++++++++++++ src/storage.c | 302 ++++++++++++++++++++++++++++++++++ storage.pc.in | 12 ++ 16 files changed, 2005 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100755 doc/storage_doc.h create mode 100644 include/common.h create mode 100644 include/list.h create mode 100644 include/log.h create mode 100644 include/storage-expand.h create mode 100644 include/storage.h create mode 100644 packaging/libstorage.manifest create mode 100644 packaging/libstorage.spec create mode 100644 src/libstorage.conf create mode 100644 src/statvfs.c create mode 100755 src/storage-internal.c create mode 100755 src/storage-sdcard.c create mode 100644 src/storage.c create mode 100644 storage.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a8afe02 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,52 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(storage C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "${PREFIX}/bin") +SET(LIBDIR ${LIB_INSTALL_DIR}) +SET(INCLUDEDIR "${PREFIX}/include/${PROJECT_NAME}") +SET(VERSION 0.1) + +SET(INC_DIR include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/${INC_DIR}) + +SET(dependents "dlog capi-base-common vconf glib-2.0") +SET(pc_dependents "capi-base-common") + +INCLUDE(FindPkgConfig) +pkg_check_modules(rpkgs REQUIRED ${dependents}) + +FOREACH(flag ${rpkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(HEADERS + include/storage.h + include/storage-expand.h) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64") +ADD_DEFINITIONS("-DENABLE_STORAGE_DLOG") + +SET(SRCS + src/statvfs.c + src/storage.c + src/storage-internal.c + src/storage-sdcard.c) + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${TARGET_SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION}) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/libstorage.conf DESTINATION /etc/${PROJECT_NAME} RENAME libstorage.conf) + +FOREACH(hfile ${HEADERS}) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${hfile} DESTINATION include/${PROJECT_NAME}) +ENDFOREACH(hfile) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4d3b53c --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/doc/storage_doc.h b/doc/storage_doc.h new file mode 100755 index 0000000..40fe64f --- /dev/null +++ b/doc/storage_doc.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_SYSTEM_STORAGE_DOC_H__ +#define __TIZEN_SYSTEM_STORAGE_DOC_H__ + +/** + * @ingroup CAPI_SYSTEM_FRAMEWORK + * @defgroup CAPI_SYSTEM_STORAGE_MODULE Storage + * @brief The STORAGE API provides functions to get storage information. + * + * @section CAPI_SYSTEM_STORAGE_MODULE_HEADER Required Header + * \#include \n + * + * @section CAPI_SYSTEM_STORAGE_MODULE_OVERVIEW Overview + * The STORAGE API provides functions to get storage information. + * + * The type of storage information includes: + * - Root directory + * - Storage type (Internal or External) + * - Storage status + * - Total and available space size + * + * The type of directory information includes: + * - Images + * - Sounds + * - Videos + * - Camera + * - Downloads + * - Music + * - Documents + * - Others + * - System ringtones + * + */ + +#endif /* __TIZEN_SYSTEM_STORAGE_DOC_H__ */ diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..1a9d987 --- /dev/null +++ b/include/common.h @@ -0,0 +1,80 @@ +/* + * storage + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "storage-expand.h" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#ifndef __WEAK__ +#define __WEAK__ __attribute__ ((weak)) +#endif + +#ifndef __CONSTRUCTOR__ +#define __CONSTRUCTOR__ __attribute__ ((constructor)) +#endif + +#ifndef __DESTRUCTOR__ +#define __DESTRUCTOR__ __attribute__ ((destructor)) +#endif + +enum storage_cb_type { + STORAGE_CALLBACK_STATE, + STORAGE_CALLBACK_MAX, +}; + +struct storage_cb_info { + int id; + storage_state_changed_cb state_cb; + void *user_data; +}; + +struct storage_ops { + storage_type_e type; + const char *(*root) (void); + int (*get_state) (void); + int (*get_space) (unsigned long long *total, unsigned long long *available); + int (*register_cb) (enum storage_cb_type type, struct storage_cb_info *info); + int (*unregister_cb) (enum storage_cb_type type, struct storage_cb_info *info); +}; + +#define STORAGE_OPS_REGISTER(st) \ +static void __CONSTRUCTOR__ module_init(void) \ +{ \ + add_device(st); \ +} \ +static void __DESTRUCTOR__ module_exit(void) \ +{ \ + remove_device(st); \ +} + +void add_device(const struct storage_ops *st); +void remove_device(const struct storage_ops *st); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/list.h b/include/list.h new file mode 100644 index 0000000..27cab68 --- /dev/null +++ b/include/list.h @@ -0,0 +1,68 @@ +/* + * storage + * + * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIST_H__ +#define __LIST_H__ + +#include + +#ifdef EINA_LIST +#include +typedef Eina_List dd_list; +#define DD_LIST_PREPEND(a, b) \ + a = eina_list_prepend(a, b) +#define DD_LIST_APPEND(a, b) \ + a = eina_list_append(a, b) +#define DD_LIST_REMOVE(a, b) \ + a = eina_list_remove(a, b) +#define DD_LIST_LENGTH(a) \ + eina_list_count(a) +#define DD_LIST_NTH(a, b) \ + eina_list_nth(a, b) +#define DD_LIST_FREE_LIST(a) \ + a = eina_list_free(a) +#define DD_LIST_FOREACH(head, elem, node) \ + EINA_LIST_FOREACH(head, elem, node) +#define DD_LIST_FOREACH_SAFE(head, elem, elem_next, node) \ + EINA_LIST_FOREACH_SAFE(head, elem, elem_next, node) + +#else +#include +typedef GList dd_list; +#define DD_LIST_PREPEND(a, b) \ + a = g_list_prepend(a, (gpointer)b) +#define DD_LIST_APPEND(a, b) \ + a = g_list_append(a, (gpointer)b) +#define DD_LIST_REMOVE(a, b) \ + a = g_list_remove(a, (gpointer)b) +#define DD_LIST_LENGTH(a) \ + g_list_length(a) +#define DD_LIST_NTH(a, b) \ + g_list_nth_data(a, b) +#define DD_LIST_FREE_LIST(a) \ + g_list_free(a) +#define DD_LIST_FOREACH(head, elem, node) \ + for (elem = head, node = NULL; elem && ((node = elem->data) != NULL); elem = elem->next, node = NULL) +#define DD_LIST_FOREACH_SAFE(head, elem, elem_next, node) \ + for (elem = head, elem_next = g_list_next(elem), node = NULL; \ + elem && ((node = elem->data) != NULL); \ + elem = elem_next, elem_next = g_list_next(elem), node = NULL) + +#endif + +#endif diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000..dfa287e --- /dev/null +++ b/include/log.h @@ -0,0 +1,57 @@ +/* + * storage + * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __LOG_H__ +#define __LOG_H__ + +#ifdef ENABLE_STORAGE_DLOG +#define ENABLE_DLOG +#endif + +#define LOG_TAG "LIBSTORAGE" + +#ifdef ENABLE_DLOG +#include +#define _D(fmt, arg...) \ + do { SLOGD(fmt, ##arg); } while(0) +#define _I(fmt, arg...) \ + do { SLOGI(fmt, ##arg); } while(0) +#define _W(fmt, arg...) \ + do { SLOGW(fmt, ##arg); } while(0) +#define _E(fmt, arg...) \ + do { SLOGE(fmt, ##arg); } while(0) +#define _SD(fmt, arg...) \ + do { SECURE_SLOGD(fmt, ##arg); } while(0) +#define _SI(fmt, arg...) \ + do { SECURE_SLOGI(fmt, ##arg); } while(0) +#define _SW(fmt, arg...) \ + do { SECURE_SLOGW(fmt, ##arg); } while(0) +#define _SE(fmt, arg...) \ + do { SECURE_SLOGE(fmt, ##arg); } while(0) +#else +#define _D(...) do { } while (0) +#define _I(...) do { } while (0) +#define _W(...) do { } while (0) +#define _E(...) do { } while (0) +#define _SD(...) do { } while (0) +#define _SI(...) do { } while (0) +#define _SW(...) do { } while (0) +#define _SE(...) do { } while (0) +#endif + +#endif diff --git a/include/storage-expand.h b/include/storage-expand.h new file mode 100644 index 0000000..454fdee --- /dev/null +++ b/include/storage-expand.h @@ -0,0 +1,331 @@ +/* + * storage + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __STORAGE_EXPAND_H__ +#define __STORAGE_EXPAND_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + /** + * @addtogroup CAPI_SYSTEM_STORAGE_MODULE + * @{ + */ + +#include + +/** + * @brief Enumeration of error codes for Storage. + * @since_tizen 2.3 + */ +typedef enum +{ + STORAGE_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + STORAGE_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + STORAGE_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + STORAGE_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NO_SUCH_DEVICE, /**< Storage not supported */ + STORAGE_ERROR_OPERATION_FAILED = TIZEN_ERROR_SYSTEM_CLASS | 0x12, /**< Operation failed */ +} storage_error_e; + + +/** + * @brief Enumeration of the storage types. + * @since_tizen 2.3 + */ +typedef enum +{ + STORAGE_TYPE_INTERNAL, /**< Internal device storage (built-in storage in a device, non-removable) */ + STORAGE_TYPE_EXTERNAL, /**< External storage */ +} storage_type_e; + + +/** + * @brief Enumeration of the state of storage devices. + * @since_tizen 2.3 + */ +typedef enum +{ + STORAGE_STATE_UNMOUNTABLE = -2, /**< Storage is present but cannot be mounted. Typically it happens if the file system of the storage is corrupted */ + STORAGE_STATE_REMOVED = -1, /**< Storage is not present */ + STORAGE_STATE_MOUNTED = 0, /**< Storage is present and mounted with read/write access */ + STORAGE_STATE_MOUNTED_READ_ONLY = 1, /**< Storage is present and mounted with read only access */ +} storage_state_e; + +/** + * @brief Called to get information once for each supported storage. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The unique storage ID + * @param[in] type The type of the storage + * @param[in] state The current state of the storage + * @param[in] path The absolute path to the root directory of the storage + * @param[in] user_data The user data passed from the foreach function + * + * @return @c true to continue with the next iteration of the loop, \n + * otherwise @c false to break out of the loop + * + * @pre storage_foreach_device_supported() will invoke this callback function. + * @see storage_foreach_device_supported() + */ +typedef bool (*storage_device_supported_cb)(int storage_id, storage_type_e type, + storage_state_e state, const char *path, void *user_data); + +/** + * @brief Retrieves all storage in a device. + * @details This function invokes the callback function once for each storage in a device. \n + * If storage_device_supported_cb() returns @c false, then the iteration will be finished. + * + * @since_tizen 2.3 + * + * @param[in] callback The iteration callback function + * @param[in] user_data The user data to be passed to the callback function + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * + * @post This function invokes storage_device_supported_cb() repeatedly for each supported device. + * @see storage_device_supported_cb() + */ +int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data); + +/** + * @brief Gets the absolute path to the root directory of the given storage. + * @details Files saved on the internal/external storage are readable or writeable by all applications. + * When an application is uninstalled, the files written by that application are not removed from the internal/external storage. + * + * @since_tizen 2.3 + * + * @remarks If you want to access files or directories in internal storage, you must declare http://tizen.org/privilege/mediastorage.\n + * If you want to access files or directories in external storage, you must declare http://tizen.org/privilege/externalstorage.\n + * You must release @a path using free(). + * + * @param[in] storage_id The storage device + * @param[out] path The absolute path to the storage directory + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * + * @see storage_get_state() + */ +int storage_get_root_directory(int storage_id, char **path); + +/** + * @brief Enumeration of the storage directory types + * @since_tizen 2.3 + */ +typedef enum +{ + STORAGE_DIRECTORY_IMAGES, /**< Image directory */ + STORAGE_DIRECTORY_SOUNDS, /**< Sounds directory */ + STORAGE_DIRECTORY_VIDEOS, /**< Videos directory */ + STORAGE_DIRECTORY_CAMERA, /**< Camera directory */ + STORAGE_DIRECTORY_DOWNLOADS, /**< Downloads directory */ + STORAGE_DIRECTORY_MUSIC, /**< Music directory */ + STORAGE_DIRECTORY_DOCUMENTS, /**< Documents directory */ + STORAGE_DIRECTORY_OTHERS, /**< Others directory */ + STORAGE_DIRECTORY_SYSTEM_RINGTONES, /**< System ringtones directory. Only available for internal storage. */ + STORAGE_DIRECTORY_MAX +} storage_directory_e; + +/** + * @brief Gets the absolute path to the each directory of the given storage. + * @details Files saved on the internal/external storage are readable or writeable by all applications. + * When an application is uninstalled, the files written by that application are not removed from the internal/external storage. + * + * @since_tizen 2.3 + * + * @remarks The directory path may not exist, so you must make sure that it exists before using it.\n + * If you want to access files or directories in internal storage except #STORAGE_DIRECTORY_SYSTEM_RINGTONES, you must declare http://tizen.org/privilege/mediastorage.\n + * If you want to access files or directories in #STORAGE_DIRECTORY_SYSTEM_RINGTONES, you must declare %http://tizen.org/privilege/systemsettings.\n + * If you want to access files or directories in external storage, you must declare http://tizen.org/privilege/externalstorage.\n + * You must release @a path using free(). + * + * @param[in] storage_id The storage device + * @param[in] type The directory type + * @param[out] path The absolute path to the directory type + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_OUT_OF_MEMORY Out of memory + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * + * @see storage_get_state() + */ +int storage_get_directory(int storage_id, storage_directory_e type, char **path); + +/** + * @brief Gets the type of the given storage. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The storage device + * @param[out] type The type of the storage + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + */ +int storage_get_type(int storage_id, storage_type_e *type); + +/** + * @brief Gets the current state of the given storage. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The storage device + * @param[out] state The current state of the storage + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * + * @see storage_get_root_directory() + * @see storage_get_total_space() + * @see storage_get_available_space() + */ +int storage_get_state(int storage_id, storage_state_e *state); + +/** + * @brief Called when the state of storage changes + * + * @since_tizen 2.3 + * + * @param[in] storage_id The unique storage ID + * @param[in] state The current state of the storage + * @param[in] user_data The user data passed from the foreach function + * + * @pre storage_set_state_changed_cb() will invoke this callback function. + * @see storage_set_state_changed_cb() + * @see storage_unset_state_changed_cb() + */ +typedef void (*storage_state_changed_cb)(int storage_id, storage_state_e state, void *user_data); + +/** + * @brief Registers a callback function to be invoked when the state of the storage changes. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The storage device + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * + * @post storage_state_changed_cb() will be invoked if the state of the registered storage changes. + * @see storage_state_changed_cb() + * @see storage_unset_state_changed_cb() + */ +int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data); + +/** + * @brief Unregisters the callback function. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The storage device to monitor + * @param[in] callback The callback function to register + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * + * @see storage_state_changed_cb() + * @see storage_set_state_changed_cb() + */ +int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback); + +/** + * @brief Gets the total space of the given storage in bytes. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The storage device + * @param[out] bytes The total space size of the storage (bytes) + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * + * @see storage_get_state() + * @see storage_get_available_space() + */ +int storage_get_total_space(int storage_id, unsigned long long *bytes); + +/** + * @brief Gets the available space size of the given storage in bytes. + * + * @since_tizen 2.3 + * + * @param[in] storage_id The storage device + * @param[out] bytes The available space size of the storage (bytes) + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval #STORAGE_ERROR_NONE Successful + * @retval #STORAGE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #STORAGE_ERROR_NOT_SUPPORTED Storage not supported + * @retval #STORAGE_ERROR_OPERATION_FAILED Operation failed + * + * @see storage_get_state() + * @see storage_get_total_space() + */ +int storage_get_available_space(int storage_id, unsigned long long *bytes); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/storage.h b/include/storage.h new file mode 100644 index 0000000..db65f18 --- /dev/null +++ b/include/storage.h @@ -0,0 +1,120 @@ +/* + * storage + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __STORAGE_H__ +#define __STORAGE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file storage.h + * @ingroup FRAMEWORK/SYSTEM + * @brief This file contains the API for the status of devices. + * @author TIZEN + * @date 2013-02-15 + * @version 0.1 + */ + + /** + * @addtogroup CAPI_SYSTEM_STORAGE_MODULE + * @{ + */ + +#include +#include "storage-expand.h" + +/** + * @fn int storage_get_internal_memory_size(struct statvfs *buf) + * @brief This generic API is used to get the internal memory size. + * + * @since_tizen 2.3 + * + * @param[out] buf A pointer to a statvfs structure + * @return @c 0 on success, + * otherwise a negative error value on failure + * @see + * @par Example: + * @code + * ... + * struct statvfs s; + * if (storage_get_internal_memory_size(&s) < 0) + * dlog_print(DLOG_DEBUG, LOG_TAG, "Fail to get internal memory size"); + * else + * dlog_print(DLOG_DEBUG, LOG_TAG, "Total mem : %lf, Avail mem : %lf", + * (double)s.f_frsize*s.f_blocks, (double)s.f_bsize*s.f_bavail); + * ... + * @endcode + */ +#ifndef __USE_FILE_OFFSET64 +extern int storage_get_internal_memory_size(struct statvfs *buf); +#else +# define storage_get_internal_memory_size storage_get_internal_memory_size64 +#endif + +#ifdef __USE_FILE_OFFSET64 +extern int storage_get_internal_memory_size64(struct statvfs *buf); +#endif + +/** + * @fn int storage_get_external_memory_size(struct statvfs *buf) + * @brief This generic API is used to get the external memory size. + * + * @since_tizen 2.3 + * + * @param[out] buf A pointer to a statvfs structure + * @return @c 0 on success, + * otherwise a negative error value on failure + * @see + * @par Example: + * @code + * ... + * struct statvfs s; + * if (storage_get_external_memory_size(&s) < 0) + * dlog_print(DLOG_DEBUG, LOG_TAG, "Fail to get external memory size"); + * else + * dlog_print(DLOG_DEBUG, LOG_TAG, "Total mem : %lf, Avail mem : %lf", + * (double)s.f_frsize*s.f_blocks, (double)s.f_bsize*s.f_bavail); + * ... + * @endcode + */ +#ifndef __USE_FILE_OFFSET64 +extern int storage_get_external_memory_size(struct statvfs *buf); +#else +# ifdef __REDIRECT_NTH +extern int __REDIRECT_NTH (storage_get_external_memory_size, + (struct statvfs *buf), storage_get_external_memory_size64) + __nonnull ((1)); +# else +# define storage_get_external_memory_size storage_get_external_memory_size64 +# endif +#endif + +#ifdef __USE_FILE_OFFSET64 +extern int storage_get_external_memory_size64(struct statvfs *buf); +#endif + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/packaging/libstorage.manifest b/packaging/libstorage.manifest new file mode 100644 index 0000000..97e8c31 --- /dev/null +++ b/packaging/libstorage.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libstorage.spec b/packaging/libstorage.spec new file mode 100644 index 0000000..d16940d --- /dev/null +++ b/packaging/libstorage.spec @@ -0,0 +1,51 @@ +Name: libstorage +Summary: Library to get storage information +Version: 0.1.0 +Release: 0 +Group: System/Libraries +License: Apache License, Version 2.0 +Source0: %{name}-%{version}.tar.gz +Source1: %{name}.manifest +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(glib-2.0) + +%description +development package of library to get storage + +%package devel +Summary: Get storage information (devel) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Library to get storage information (devel) + + +%prep +%setup -q +cp %{SOURCE1} . + +%build +%cmake . +make %{?jobs:-j%jobs} + +%install +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%{_libdir}/*.so.* +%{_sysconfdir}/storage/libstorage.conf +%license LICENSE +%manifest %{name}.manifest + +%files devel +%{_includedir}/storage/*.h +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc diff --git a/src/libstorage.conf b/src/libstorage.conf new file mode 100644 index 0000000..67f1325 --- /dev/null +++ b/src/libstorage.conf @@ -0,0 +1,7 @@ +[STORAGE] +#reserved level check size 1GB +CHECK_SIZE=1073741824 +#100MB +RESERVE=104857600 +#5MB +RESERVE_LITE=5242880 diff --git a/src/statvfs.c b/src/statvfs.c new file mode 100644 index 0000000..ca2c62b --- /dev/null +++ b/src/statvfs.c @@ -0,0 +1,374 @@ +/* + * storage + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "common.h" + +#define MEMORY_GIGABYTE_VALUE 1073741824 +#define MEMORY_MEGABYTE_VALUE 1048576 + +#define MEMORY_STATUS_USR_PATH "/opt/usr" +#define EXTERNAL_MEMORY_PATH "/opt/storage/sdcard" +#define STORAGE_CONF_FILE "/etc/storage/libstorage.conf" + +/* it's for 32bit file offset */ +struct statvfs_32 { + unsigned long int f_bsize; + unsigned long int f_frsize; + unsigned long int f_blocks; + unsigned long int f_bfree; + unsigned long int f_bavail; + unsigned long int f_files; + unsigned long int f_ffree; + unsigned long int f_favail; + unsigned long int f_fsid; +#ifdef _STATVFSBUF_F_UNUSED + int __f_unused; +#endif + unsigned long int f_flag; + unsigned long int f_namemax; + int __f_spare[6]; +}; + +#define MAX_LINE 128 +#define MAX_SECTION 64 +#define WHITESPACE " \t" +#define NEWLINE "\n\r" +#define COMMENT '#' + +#define MATCH(a, b) (!strncmp(a, b, strlen(a))) +#define SET_CONF(a, b) (a = (b > 0.0 ? b : a)) + +struct parse_result { + char *section; + char *name; + char *value; +}; + +struct storage_config_info { + double total_size; + double check_size; + double reserved_size; +}; + +static struct storage_config_info storage_info; + +static inline char *trim_str(char *s) +{ + char *t; + /* left trim */ + s += strspn(s, WHITESPACE); + + /* right trim */ + for (t = strchr(s, 0); t > s; t--) + if (!strchr(WHITESPACE, t[-1])) + break; + *t = 0; + return s; +} + +static int config_parse(const char *file_name, int cb(struct parse_result *result, + void *user_data), void *user_data) +{ + FILE *f = NULL; + struct parse_result result; + /* use stack for parsing */ + char line[MAX_LINE]; + char section[MAX_SECTION]; + char *start, *end, *name, *value; + int lineno = 0, ret = 0; + + if (!file_name || !cb) { + ret = -EINVAL; + goto error; + } + + /* open conf file */ + f = fopen(file_name, "r"); + if (!f) { + _E("Failed to open file %s", file_name); + ret = -EIO; + goto error; + } + + /* parsing line by line */ + while (fgets(line, MAX_LINE, f) != NULL) { + lineno++; + + start = line; + start[strcspn(start, NEWLINE)] = '\0'; + start = trim_str(start); + + if (*start == COMMENT) { + continue; + } else if (*start == '[') { + /* parse section */ + end = strchr(start, ']'); + if (!end || *end != ']') { + ret = -EBADMSG; + goto error; + } + + *end = '\0'; + strncpy(section, start + 1, sizeof(section)); + section[MAX_SECTION-1] = '\0'; + } else if (*start) { + /* parse name & value */ + end = strchr(start, '='); + if (!end || *end != '=') { + ret = -EBADMSG; + goto error; + } + *end = '\0'; + name = trim_str(start); + value = trim_str(end + 1); + end = strchr(value, COMMENT); + if (end && *end == COMMENT) { + *end = '\0'; + value = trim_str(value); + } + + result.section = section; + result.name = name; + result.value = value; + /* callback with parse result */ + ret = cb(&result, user_data); + if (ret < 0) { + ret = -EBADMSG; + goto error; + } + } + } + _D("Success to load %s", file_name); + fclose(f); + return 0; + +error: + if (f) + fclose(f); + _E("Failed to read %s:%d!", file_name, lineno); + return ret; +} + +static int load_config(struct parse_result *result, void *user_data) +{ + static int check_size = -1; + struct storage_config_info *info = (struct storage_config_info *)user_data; + char *name; + char *value; + + if (!info) + return -EINVAL; + + if (!MATCH(result->section, "STORAGE")) + return -EINVAL; + + name = result->name; + value = result->value; + + if (info->check_size > 0 && check_size < 0) + check_size = (storage_info.total_size < info->check_size)? 1 : 0; + if (MATCH(name, "CHECK_SIZE")) + info->check_size = atoi(value); + else if (check_size == 0 && MATCH(name, "RESERVE")) + info->reserved_size = atoi(value); + else if (check_size == 1 && MATCH(name, "RESERVE_LITE")) + info->reserved_size = atoi(value); + + return 0; +} + +static void storage_config_load(struct storage_config_info *info) +{ + int ret; + + ret = config_parse(STORAGE_CONF_FILE, load_config, info); + if (ret < 0) + _E("Failed to load %s, %d Use default value!", STORAGE_CONF_FILE, ret); +} + +static int get_memory_size(const char *path, struct statvfs_32 *buf) +{ + struct statvfs s; + int ret; + + assert(buf); + + ret = statvfs(path, &s); + if (ret) + return -errno; + + buf->f_bsize = s.f_bsize; + buf->f_frsize = s.f_frsize; + buf->f_blocks = (unsigned long)s.f_blocks; + buf->f_bfree = (unsigned long)s.f_bfree; + buf->f_bavail = (unsigned long)s.f_bavail; + buf->f_files = (unsigned long)s.f_files; + buf->f_ffree = (unsigned long)s.f_ffree; + buf->f_favail = (unsigned long)s.f_favail; + buf->f_fsid = s.f_fsid; + buf->f_flag = s.f_flag; + buf->f_namemax = s.f_namemax; + + return 0; +} + +API int storage_get_internal_memory_size(struct statvfs *buf) +{ + struct statvfs_32 temp; + static unsigned long reserved = 0; + int ret; + + if (!buf) { + _E("input param error"); + return -EINVAL; + } + + ret = get_memory_size(MEMORY_STATUS_USR_PATH, &temp); + if (ret) { + _E("fail to get memory size"); + return -errno; + } + + if (reserved == 0) { + storage_info.total_size = (double)temp.f_frsize * temp.f_blocks; + storage_config_load(&storage_info); + reserved = (unsigned long)storage_info.reserved_size; + reserved = reserved/temp.f_bsize; + _I("total %4.4lf check %4.4lf reserved %4.4lf", + storage_info.total_size, storage_info.check_size, storage_info.reserved_size); + } + if (temp.f_bavail < reserved) + temp.f_bavail = 0; + else + temp.f_bavail -= reserved; + + memcpy(buf, &temp, sizeof(temp)); + return 0; +} + +API int storage_get_internal_memory_size64(struct statvfs *buf) +{ + static unsigned long reserved = 0; + int ret; + + if (!buf) { + _E("input param error"); + return -EINVAL; + } + + ret = statvfs(MEMORY_STATUS_USR_PATH, buf); + if (ret) { + _E("fail to get memory size"); + return -errno; + } + + if (reserved == 0) { + storage_info.total_size = (double)(buf->f_frsize * buf->f_blocks); + storage_config_load(&storage_info); + reserved = (unsigned long)storage_info.reserved_size; + reserved = reserved/buf->f_bsize; + _I("total %4.4lf check %4.4lf reserved %4.4lf", + storage_info.total_size, storage_info.check_size, storage_info.reserved_size); + } + if (buf->f_bavail < reserved) + buf->f_bavail = 0; + else + buf->f_bavail -= reserved; + return 0; +} + +static int mount_check(const char* path) +{ + int ret = false; + struct mntent* mnt; + const char* table = "/etc/mtab"; + FILE* fp; + + fp = setmntent(table, "r"); + if (!fp) + return ret; + while ((mnt=getmntent(fp))) { + if (!strcmp(mnt->mnt_dir, path)) { + ret = true; + break; + } + } + endmntent(fp); + return ret; +} + +API int storage_get_external_memory_size(struct statvfs *buf) +{ + struct statvfs_32 temp; + int ret; + + _D("storage_get_external_memory_size"); + if (!buf) { + _E("input param error"); + return -EINVAL; + } + + if (!mount_check(EXTERNAL_MEMORY_PATH)) { + memset(buf, 0, sizeof(struct statvfs_32)); + return 0; + } + + ret = get_memory_size(EXTERNAL_MEMORY_PATH, &temp); + if (ret) { + _E("fail to get memory size"); + return -errno; + } + + memcpy(buf, &temp, sizeof(temp)); + return 0; +} + +API int storage_get_external_memory_size64(struct statvfs *buf) +{ + int ret; + + _D("storage_get_external_memory_size64"); + if (!buf) { + _E("input param error"); + return -EINVAL; + } + + if (!mount_check(EXTERNAL_MEMORY_PATH)) { + memset(buf, 0, sizeof(struct statvfs)); + return 0; + } + + ret = statvfs(EXTERNAL_MEMORY_PATH, buf); + if (ret) { + _E("fail to get memory size"); + return -errno; + } + + return 0; +} diff --git a/src/storage-internal.c b/src/storage-internal.c new file mode 100755 index 0000000..036ca34 --- /dev/null +++ b/src/storage-internal.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "log.h" + +#define INTERNAL_MEMORY_PATH "/opt/usr/media" + +#ifndef __USE_FILE_OFFSET64 +int __WEAK__ storage_get_internal_memory_size(struct statvfs *buf); +#else +int __WEAK__ storage_get_internal_memory_size64(struct statvfs *buf); +#endif + +static int internal_get_state(void) +{ + return STORAGE_STATE_MOUNTED; +} + +static int internal_get_space(unsigned long long *total, unsigned long long *available) +{ + struct statvfs s; + int ret; + +#ifndef __USE_FILE_OFFSET64 + ret = storage_get_internal_memory_size(&s); +#else + ret = storage_get_internal_memory_size64(&s); +#endif + if (ret < 0) + return -EPERM; + + if (total) + *total = (unsigned long long)s.f_frsize*s.f_blocks; + if (available) + *available = (unsigned long long)s.f_bsize*s.f_bavail; + return 0; +} + +static const char *internal_get_root(void) +{ + return INTERNAL_MEMORY_PATH; +} + +const struct storage_ops internal = { + .type = STORAGE_TYPE_INTERNAL, + .root = internal_get_root, + .get_state = internal_get_state, + .get_space = internal_get_space, +}; + +STORAGE_OPS_REGISTER(&internal) diff --git a/src/storage-sdcard.c b/src/storage-sdcard.c new file mode 100755 index 0000000..65747af --- /dev/null +++ b/src/storage-sdcard.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "list.h" +#include "log.h" + +#define SDCARD_PATH "/opt/storage/sdcard" + +#ifndef __USE_FILE_OFFSET64 +int __WEAK__ storage_get_external_memory_size(struct statvfs *buf); +#else +int __WEAK__ storage_get_external_memory_size64(struct statvfs *buf); +#endif + +static dd_list *cb_list[STORAGE_CALLBACK_MAX]; + +static int sdcard_get_state(void) +{ + int val, ret; + + ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &val); + if (ret < 0) + return -EPERM; + + switch (val) { + case VCONFKEY_SYSMAN_MMC_MOUNTED: + return STORAGE_STATE_MOUNTED; + case VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED: + return STORAGE_STATE_UNMOUNTABLE; + case VCONFKEY_SYSMAN_MMC_REMOVED: + default: + break; + } + + return STORAGE_STATE_REMOVED; +} + +static int sdcard_get_space(unsigned long long *total, unsigned long long *available) +{ + storage_state_e state; + struct statvfs s; + int ret, t, a; + + state = sdcard_get_state(); + if (state < STORAGE_STATE_MOUNTED) { + t = 0; + a = 0; + } else { /* if sdcard is mounted */ +#ifndef __USE_FILE_OFFSET64 + ret = storage_get_external_memory_size(&s); +#else + ret = storage_get_external_memory_size64(&s); +#endif + if (ret < 0) + return -EPERM; + + t = (unsigned long long)s.f_frsize*s.f_blocks; + a = (unsigned long long)s.f_bsize*s.f_bavail; + } + + if (total) + *total = t; + if (available) + *available = a; + + return 0; +} + +static const char *sdcard_get_root(void) +{ + return SDCARD_PATH; +} + +static void sdcard_state_cb(keynode_t* key, void* data) +{ + struct storage_cb_info *cb_info; + dd_list *elem; + storage_state_e state; + + state = sdcard_get_state(); + + DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info) + cb_info->state_cb(cb_info->id, state, cb_info->user_data); +} + +static int register_request(enum storage_cb_type type) +{ + switch (type) { + case STORAGE_CALLBACK_STATE: + return vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, + sdcard_state_cb, NULL); + default: + break; + } + + return -EINVAL; +} + +static int release_request(enum storage_cb_type type) +{ + switch (type) { + case STORAGE_CALLBACK_STATE: + return vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, + sdcard_state_cb); + default: + break; + } + + return -EINVAL; +} + +static int sdcard_register_cb(enum storage_cb_type type, struct storage_cb_info *info) +{ + struct storage_cb_info *cb_info; + dd_list *elem; + int ret, n; + + if (type < 0 || type >= STORAGE_CALLBACK_MAX) + return -EINVAL; + + if (!info) + return -EINVAL; + + /* check if it is the first request */ + n = DD_LIST_LENGTH(cb_list[type]); + if (n == 0) { + ret = register_request(type); + if (ret < 0) + return -EPERM; + } + + /* check for the same request */ + DD_LIST_FOREACH(cb_list[type], elem, cb_info) { + if (cb_info->id == info->id && + cb_info->state_cb == info->state_cb) + return -EEXIST; + } + + /* add device changed callback to list (local) */ + cb_info = malloc(sizeof(struct storage_cb_info)); + if (!cb_info) + return -errno; + + memcpy(cb_info, info, sizeof(struct storage_cb_info)); + DD_LIST_APPEND(cb_list[type], cb_info); + + return 0; +} + +static int sdcard_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info) +{ + struct storage_cb_info *cb_info; + dd_list *elem; + int ret, n; + + if (type < 0 || type >= STORAGE_CALLBACK_MAX) + return -EINVAL; + + if (!info) + return -EINVAL; + + /* search for the same element with callback */ + DD_LIST_FOREACH(cb_list[type], elem, cb_info) { + if (cb_info->id == info->id && + cb_info->state_cb == info->state_cb) + break; + } + + if (!cb_info) + return -EINVAL; + + /* remove device callback from list (local) */ + DD_LIST_REMOVE(cb_list[type], cb_info); + free(cb_info); + + /* check if this callback is last element */ + n = DD_LIST_LENGTH(cb_list[type]); + if (n == 0) { + ret = release_request(type); + if (ret < 0) + return -EPERM; + } + + return 0; +} + +const struct storage_ops sdcard = { + .type = STORAGE_TYPE_EXTERNAL, + .root = sdcard_get_root, + .get_state = sdcard_get_state, + .get_space = sdcard_get_space, + .register_cb = sdcard_register_cb, + .unregister_cb = sdcard_unregister_cb, +}; + +STORAGE_OPS_REGISTER(&sdcard) diff --git a/src/storage.c b/src/storage.c new file mode 100644 index 0000000..480ef05 --- /dev/null +++ b/src/storage.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include +#include + +#include "common.h" +#include "list.h" +#include "log.h" + +const char *dir_path[STORAGE_DIRECTORY_MAX] = { + [STORAGE_DIRECTORY_IMAGES] = "Images", + [STORAGE_DIRECTORY_SOUNDS] = "Sounds", + [STORAGE_DIRECTORY_VIDEOS] = "Videos", + [STORAGE_DIRECTORY_CAMERA] = "DCIM", + [STORAGE_DIRECTORY_DOWNLOADS] = "Downloads", + [STORAGE_DIRECTORY_MUSIC] = "Music", + [STORAGE_DIRECTORY_DOCUMENTS] = "Documents", + [STORAGE_DIRECTORY_OTHERS] = "Others", + [STORAGE_DIRECTORY_SYSTEM_RINGTONES] = "/opt/usr/share/settings/Ringtones", +}; + +static dd_list *st_head; + +void add_device(const struct storage_ops *st) +{ + DD_LIST_APPEND(st_head, st); +} + +void remove_device(const struct storage_ops *st) +{ + DD_LIST_REMOVE(st_head, st); +} + +API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data) +{ + const struct storage_ops *st; + dd_list *elem; + int storage_id = 0, ret; + + if (!callback) { + _E("Invalid parameter"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + DD_LIST_FOREACH(st_head, elem, st) { + ret = callback(storage_id, st->type, st->get_state(), + st->root(), user_data); + /* if the return value is false, will be stop to iterate */ + if (!ret) + break; + storage_id++; + } + + return STORAGE_ERROR_NONE; +} + +API int storage_get_root_directory(int storage_id, char **path) +{ + const struct storage_ops *st; + + if (!path) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + *path = strdup(st->root()); + if (!*path) { + _E("Failed to copy the root string : %s", strerror(errno)); + return STORAGE_ERROR_OUT_OF_MEMORY; + } + + return STORAGE_ERROR_NONE; +} + +API int storage_get_directory(int storage_id, storage_directory_e type, char **path) +{ + const struct storage_ops *st; + const char *root; + char temp[PATH_MAX]; + + if (!path) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + if (type < 0 || type >= STORAGE_DIRECTORY_MAX) { + _E("Invalid parameter"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + if (st->type != STORAGE_TYPE_INTERNAL + && type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) { + _E("Not support directory : id(%d) type(%d)", storage_id, type); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + root = st->root(); + if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) + snprintf(temp, PATH_MAX, "%s", dir_path[type]); + else + snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]); + + *path = strdup(temp); + if (!*path) { + _E("Failed to copy the directory(%d) string : %s", type, strerror(errno)); + return STORAGE_ERROR_OUT_OF_MEMORY; + } + + return STORAGE_ERROR_NONE; +} + +API int storage_get_type(int storage_id, storage_type_e *type) +{ + const struct storage_ops *st; + + if (!type) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + *type = st->type; + + return STORAGE_ERROR_NONE; +} + +API int storage_get_state(int storage_id, storage_state_e *state) +{ + const struct storage_ops *st; + + if (!state) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + *state = st->get_state(); + + return STORAGE_ERROR_NONE; +} + +API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data) +{ + const struct storage_ops *st; + struct storage_cb_info info; + int ret; + + if (!callback) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + /* do not register changed callback in case of internal memory */ + if (st->type == STORAGE_TYPE_INTERNAL) + return STORAGE_ERROR_NONE; + + info.id = storage_id; + info.state_cb = callback; + info.user_data = user_data; + + ret = st->register_cb(STORAGE_CALLBACK_STATE, &info); + if (ret < 0) { + _E("Failed to register callback : id(%d)", storage_id); + return STORAGE_ERROR_OPERATION_FAILED; + } + + return STORAGE_ERROR_NONE; +} + +API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback) +{ + const struct storage_ops *st; + struct storage_cb_info info; + int ret; + + if (!callback) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + /* in case of internal memory, it does not register changed callback */ + if (st->type == STORAGE_TYPE_INTERNAL) + return STORAGE_ERROR_NONE; + + info.id = storage_id; + info.state_cb = callback; + + ret = st->unregister_cb(STORAGE_CALLBACK_STATE, &info); + if (ret < 0) { + _E("Failed to unregister callback : id(%d)", storage_id); + return STORAGE_ERROR_OPERATION_FAILED; + } + + return STORAGE_ERROR_NONE; +} + +API int storage_get_total_space(int storage_id, unsigned long long *bytes) +{ + const struct storage_ops *st; + unsigned long long total; + int ret; + + if (!bytes) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + ret = st->get_space(&total, NULL); + if (ret < 0) { + _E("Failed to get total memory : id(%d)", storage_id); + return STORAGE_ERROR_OPERATION_FAILED; + } + + *bytes = total; + + return STORAGE_ERROR_NONE; +} + +API int storage_get_available_space(int storage_id, unsigned long long *bytes) +{ + const struct storage_ops *st; + unsigned long long avail; + int ret; + + if (!bytes) { + _E("Invalid parameger"); + return STORAGE_ERROR_INVALID_PARAMETER; + } + + st = DD_LIST_NTH(st_head, storage_id); + if (!st) { + _E("Not supported storage : id(%d)", storage_id); + return STORAGE_ERROR_NOT_SUPPORTED; + } + + ret = st->get_space(NULL, &avail); + if (ret < 0) { + _E("Failed to get available memory : id(%d)", storage_id); + return STORAGE_ERROR_OPERATION_FAILED; + } + + *bytes = avail; + + return STORAGE_ERROR_NONE; +} diff --git a/storage.pc.in b/storage.pc.in new file mode 100644 index 0000000..98aef8a --- /dev/null +++ b/storage.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDEDIR@ + +Name: Storage library +Description: Library to get storage information +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} -lstorage @PC_LDFLAGS@ +Cflags: -I${includedir} -- 2.7.4 From b1fbcda1bd8024cdb6f8b0d93a9cf6566e36f306 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Thu, 16 Apr 2015 12:50:30 +0900 Subject: [PATCH 03/11] libstorage: Change the since_tizen string for wearable Change-Id: I2400fef8924b6a6a5af6f5a3b5c82328d81bc37b Signed-off-by: Jiyoung Yun --- include/storage-expand.h | 30 +++++++++++++++--------------- include/storage.h | 4 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/storage-expand.h b/include/storage-expand.h index 454fdee..83f3491 100644 --- a/include/storage-expand.h +++ b/include/storage-expand.h @@ -33,7 +33,7 @@ extern "C" { /** * @brief Enumeration of error codes for Storage. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -47,7 +47,7 @@ typedef enum /** * @brief Enumeration of the storage types. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -58,7 +58,7 @@ typedef enum /** * @brief Enumeration of the state of storage devices. - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -71,7 +71,7 @@ typedef enum /** * @brief Called to get information once for each supported storage. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The unique storage ID * @param[in] type The type of the storage @@ -93,7 +93,7 @@ typedef bool (*storage_device_supported_cb)(int storage_id, storage_type_e type, * @details This function invokes the callback function once for each storage in a device. \n * If storage_device_supported_cb() returns @c false, then the iteration will be finished. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] callback The iteration callback function * @param[in] user_data The user data to be passed to the callback function @@ -114,7 +114,7 @@ int storage_foreach_device_supported(storage_device_supported_cb callback, void * @details Files saved on the internal/external storage are readable or writeable by all applications. * When an application is uninstalled, the files written by that application are not removed from the internal/external storage. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @remarks If you want to access files or directories in internal storage, you must declare http://tizen.org/privilege/mediastorage.\n * If you want to access files or directories in external storage, you must declare http://tizen.org/privilege/externalstorage.\n @@ -137,7 +137,7 @@ int storage_get_root_directory(int storage_id, char **path); /** * @brief Enumeration of the storage directory types - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -158,7 +158,7 @@ typedef enum * @details Files saved on the internal/external storage are readable or writeable by all applications. * When an application is uninstalled, the files written by that application are not removed from the internal/external storage. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @remarks The directory path may not exist, so you must make sure that it exists before using it.\n * If you want to access files or directories in internal storage except #STORAGE_DIRECTORY_SYSTEM_RINGTONES, you must declare http://tizen.org/privilege/mediastorage.\n @@ -185,7 +185,7 @@ int storage_get_directory(int storage_id, storage_directory_e type, char **path) /** * @brief Gets the type of the given storage. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The storage device * @param[out] type The type of the storage @@ -202,7 +202,7 @@ int storage_get_type(int storage_id, storage_type_e *type); /** * @brief Gets the current state of the given storage. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The storage device * @param[out] state The current state of the storage @@ -223,7 +223,7 @@ int storage_get_state(int storage_id, storage_state_e *state); /** * @brief Called when the state of storage changes * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The unique storage ID * @param[in] state The current state of the storage @@ -238,7 +238,7 @@ typedef void (*storage_state_changed_cb)(int storage_id, storage_state_e state, /** * @brief Registers a callback function to be invoked when the state of the storage changes. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The storage device * @param[in] callback The callback function to register @@ -261,7 +261,7 @@ int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callba /** * @brief Unregisters the callback function. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The storage device to monitor * @param[in] callback The callback function to register @@ -282,7 +282,7 @@ int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb call /** * @brief Gets the total space of the given storage in bytes. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The storage device * @param[out] bytes The total space size of the storage (bytes) @@ -303,7 +303,7 @@ int storage_get_total_space(int storage_id, unsigned long long *bytes); /** * @brief Gets the available space size of the given storage in bytes. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[in] storage_id The storage device * @param[out] bytes The available space size of the storage (bytes) diff --git a/include/storage.h b/include/storage.h index db65f18..7370582 100644 --- a/include/storage.h +++ b/include/storage.h @@ -44,7 +44,7 @@ extern "C" { * @fn int storage_get_internal_memory_size(struct statvfs *buf) * @brief This generic API is used to get the internal memory size. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[out] buf A pointer to a statvfs structure * @return @c 0 on success, @@ -76,7 +76,7 @@ extern int storage_get_internal_memory_size64(struct statvfs *buf); * @fn int storage_get_external_memory_size(struct statvfs *buf) * @brief This generic API is used to get the external memory size. * - * @since_tizen 2.3 + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * * @param[out] buf A pointer to a statvfs structure * @return @c 0 on success, -- 2.7.4 From 1ed1220fc817b109368d1f587c75faa1d3057b46 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Thu, 21 May 2015 17:03:05 +0900 Subject: [PATCH 04/11] libstorage: Add memory size check routine If a memory size is zero, it does not try to divide by zero. Change-Id: Ieeff37b0d527f0edba7d06f54f4f31081632f9b9 Signed-off-by: Jiyoung Yun --- src/statvfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/statvfs.c b/src/statvfs.c index ca2c62b..81d323f 100644 --- a/src/statvfs.c +++ b/src/statvfs.c @@ -250,7 +250,7 @@ API int storage_get_internal_memory_size(struct statvfs *buf) } ret = get_memory_size(MEMORY_STATUS_USR_PATH, &temp); - if (ret) { + if (ret || temp.f_bsize == 0) { _E("fail to get memory size"); return -errno; } -- 2.7.4 From ff98211fd608bfc88edbb805eaf3d8e362108ade Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 3 Jun 2015 11:47:20 +0900 Subject: [PATCH 05/11] libstorage: Support multi user by using tzplatform library Storeage apis will return the proper directory path as per user accoount. Signed-off-by: Jiyoung Yun Change-Id: I35e249a9396f52de0c09191e88f3cac89f758f92 --- CMakeLists.txt | 2 +- packaging/libstorage.spec | 1 + src/storage-internal.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a8afe02..f621ade 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ SET(VERSION 0.1) SET(INC_DIR include) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/${INC_DIR}) -SET(dependents "dlog capi-base-common vconf glib-2.0") +SET(dependents "dlog capi-base-common vconf glib-2.0 libtzplatform-config") SET(pc_dependents "capi-base-common") INCLUDE(FindPkgConfig) diff --git a/packaging/libstorage.spec b/packaging/libstorage.spec index d16940d..501ed0d 100644 --- a/packaging/libstorage.spec +++ b/packaging/libstorage.spec @@ -11,6 +11,7 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(libtzplatform-config) %description development package of library to get storage diff --git a/src/storage-internal.c b/src/storage-internal.c index 036ca34..ca8b182 100755 --- a/src/storage-internal.c +++ b/src/storage-internal.c @@ -21,11 +21,11 @@ #include #include #include +#include #include "common.h" #include "log.h" -#define INTERNAL_MEMORY_PATH "/opt/usr/media" #ifndef __USE_FILE_OFFSET64 int __WEAK__ storage_get_internal_memory_size(struct statvfs *buf); @@ -60,7 +60,7 @@ static int internal_get_space(unsigned long long *total, unsigned long long *ava static const char *internal_get_root(void) { - return INTERNAL_MEMORY_PATH; + return tzplatform_getenv(TZ_USER_CONTENT); } const struct storage_ops internal = { -- 2.7.4 From fbb974d6a6eda4d3ed1fc6975e2b0dd77b72f3dd Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Tue, 28 Jul 2015 15:57:42 +0900 Subject: [PATCH 06/11] libstorage: Do not use thread-unsafe function and code clearance strerror() is not safety on multi thread environment. Add initialize input buffer. Signed-off-by: Jiyoung Yun Change-Id: I159b6a2162ef73e1dd337910a5b2e9a80e1354bd --- src/statvfs.c | 14 ++++++++------ src/storage-sdcard.c | 2 +- src/storage.c | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/statvfs.c b/src/statvfs.c index 81d323f..ff93b21 100644 --- a/src/statvfs.c +++ b/src/statvfs.c @@ -192,7 +192,7 @@ static int load_config(struct parse_result *result, void *user_data) value = result->value; if (info->check_size > 0 && check_size < 0) - check_size = (storage_info.total_size < info->check_size)? 1 : 0; + check_size = (storage_info.total_size < info->check_size) ? 1 : 0; if (MATCH(name, "CHECK_SIZE")) info->check_size = atoi(value); else if (check_size == 0 && MATCH(name, "RESERVE")) @@ -223,6 +223,8 @@ static int get_memory_size(const char *path, struct statvfs_32 *buf) if (ret) return -errno; + memset(buf, 0, sizeof(struct statvfs_32)); + buf->f_bsize = s.f_bsize; buf->f_frsize = s.f_frsize; buf->f_blocks = (unsigned long)s.f_blocks; @@ -303,17 +305,17 @@ API int storage_get_internal_memory_size64(struct statvfs *buf) return 0; } -static int mount_check(const char* path) +static int mount_check(const char *path) { int ret = false; - struct mntent* mnt; - const char* table = "/etc/mtab"; - FILE* fp; + struct mntent *mnt; + const char *table = "/etc/mtab"; + FILE *fp; fp = setmntent(table, "r"); if (!fp) return ret; - while ((mnt=getmntent(fp))) { + while ((mnt = getmntent(fp))) { if (!strcmp(mnt->mnt_dir, path)) { ret = true; break; diff --git a/src/storage-sdcard.c b/src/storage-sdcard.c index 65747af..fc02c6b 100755 --- a/src/storage-sdcard.c +++ b/src/storage-sdcard.c @@ -93,7 +93,7 @@ static const char *sdcard_get_root(void) return SDCARD_PATH; } -static void sdcard_state_cb(keynode_t* key, void* data) +static void sdcard_state_cb(keynode_t *key, void *data) { struct storage_cb_info *cb_info; dd_list *elem; diff --git a/src/storage.c b/src/storage.c index 480ef05..cbe34b5 100644 --- a/src/storage.c +++ b/src/storage.c @@ -88,7 +88,7 @@ API int storage_get_root_directory(int storage_id, char **path) *path = strdup(st->root()); if (!*path) { - _E("Failed to copy the root string : %s", strerror(errno)); + _E("Failed to copy the root string : %d", errno); return STORAGE_ERROR_OUT_OF_MEMORY; } @@ -131,7 +131,7 @@ API int storage_get_directory(int storage_id, storage_directory_e type, char **p *path = strdup(temp); if (!*path) { - _E("Failed to copy the directory(%d) string : %s", type, strerror(errno)); + _E("Failed to copy the directory(%d) string : %d", type, errno); return STORAGE_ERROR_OUT_OF_MEMORY; } -- 2.7.4 From 6afbb917317fbf2a3a5d8b42db321721a5d5ead3 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Tue, 28 Jul 2015 16:03:59 +0900 Subject: [PATCH 07/11] libstorage: Fixed wrong space value The size of unsigned long long is not the same with int's size. But it has copied int value to unsigned long long value. It makes wrong copy operation. Change-Id: Ief253146585ffc7474f9bd623c4680c8d516ede5 Signed-off-by: Jiyoung Yun --- src/storage-sdcard.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/storage-sdcard.c b/src/storage-sdcard.c index fc02c6b..70be220 100755 --- a/src/storage-sdcard.c +++ b/src/storage-sdcard.c @@ -61,13 +61,11 @@ static int sdcard_get_space(unsigned long long *total, unsigned long long *avail { storage_state_e state; struct statvfs s; - int ret, t, a; + int ret; + unsigned long long t = 0, a = 0; state = sdcard_get_state(); - if (state < STORAGE_STATE_MOUNTED) { - t = 0; - a = 0; - } else { /* if sdcard is mounted */ + if (state >= STORAGE_STATE_MOUNTED) { #ifndef __USE_FILE_OFFSET64 ret = storage_get_external_memory_size(&s); #else -- 2.7.4 From 6a7107e384c259a7a17781206bdcc87af24ddab4 Mon Sep 17 00:00:00 2001 From: Taeyoung Kim Date: Thu, 27 Aug 2015 21:40:40 +0900 Subject: [PATCH 08/11] storage: change directory name "DCIM" to "Camera" - The policy for directory name of camera is changed from "DCIM" to "Camera" Change-Id: I0f7e42a6ffbfe5045447d69a8f61edcff749fb05 Signed-off-by: Taeyoung Kim --- src/storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage.c b/src/storage.c index cbe34b5..4ea9171 100644 --- a/src/storage.c +++ b/src/storage.c @@ -28,7 +28,7 @@ const char *dir_path[STORAGE_DIRECTORY_MAX] = { [STORAGE_DIRECTORY_IMAGES] = "Images", [STORAGE_DIRECTORY_SOUNDS] = "Sounds", [STORAGE_DIRECTORY_VIDEOS] = "Videos", - [STORAGE_DIRECTORY_CAMERA] = "DCIM", + [STORAGE_DIRECTORY_CAMERA] = "Camera", [STORAGE_DIRECTORY_DOWNLOADS] = "Downloads", [STORAGE_DIRECTORY_MUSIC] = "Music", [STORAGE_DIRECTORY_DOCUMENTS] = "Documents", -- 2.7.4 From 24349267be9d7343a777301f940862d367227735 Mon Sep 17 00:00:00 2001 From: taeyoung Date: Thu, 10 Sep 2015 18:00:44 +0900 Subject: [PATCH 09/11] sdcard: change root path of sdcard - Previously, the sdcard root path is hard-coded to /opt/storage/sdcard But the directory policy is changed and the policy can be obtained by libtzplatform-config. Thus the path is changed Change-Id: Id1808bc6c67e0f54d272c332d27351ca81fec842 Signed-off-by: taeyoung --- src/statvfs.c | 17 ++++++++++++----- src/storage-sdcard.c | 5 +++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/statvfs.c b/src/statvfs.c index ff93b21..859f43d 100644 --- a/src/statvfs.c +++ b/src/statvfs.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "log.h" #include "common.h" @@ -33,7 +34,7 @@ #define MEMORY_MEGABYTE_VALUE 1048576 #define MEMORY_STATUS_USR_PATH "/opt/usr" -#define EXTERNAL_MEMORY_PATH "/opt/storage/sdcard" +#define EXTERNAL_MEMORY_NODE "sdcard" #define STORAGE_CONF_FILE "/etc/storage/libstorage.conf" /* it's for 32bit file offset */ @@ -325,6 +326,12 @@ static int mount_check(const char *path) return ret; } +static const char *get_external_path(void) +{ + return tzplatform_mkpath(TZ_SYS_STORAGE, + EXTERNAL_MEMORY_NODE); +} + API int storage_get_external_memory_size(struct statvfs *buf) { struct statvfs_32 temp; @@ -336,12 +343,12 @@ API int storage_get_external_memory_size(struct statvfs *buf) return -EINVAL; } - if (!mount_check(EXTERNAL_MEMORY_PATH)) { + if (!mount_check(get_external_path())) { memset(buf, 0, sizeof(struct statvfs_32)); return 0; } - ret = get_memory_size(EXTERNAL_MEMORY_PATH, &temp); + ret = get_memory_size(get_external_path(), &temp); if (ret) { _E("fail to get memory size"); return -errno; @@ -361,12 +368,12 @@ API int storage_get_external_memory_size64(struct statvfs *buf) return -EINVAL; } - if (!mount_check(EXTERNAL_MEMORY_PATH)) { + if (!mount_check(get_external_path())) { memset(buf, 0, sizeof(struct statvfs)); return 0; } - ret = statvfs(EXTERNAL_MEMORY_PATH, buf); + ret = statvfs(get_external_path(), buf); if (ret) { _E("fail to get memory size"); return -errno; diff --git a/src/storage-sdcard.c b/src/storage-sdcard.c index 70be220..8d6dcbd 100755 --- a/src/storage-sdcard.c +++ b/src/storage-sdcard.c @@ -21,12 +21,13 @@ #include #include #include +#include #include "common.h" #include "list.h" #include "log.h" -#define SDCARD_PATH "/opt/storage/sdcard" +#define SDCARD_NODE "sdcard" #ifndef __USE_FILE_OFFSET64 int __WEAK__ storage_get_external_memory_size(struct statvfs *buf); @@ -88,7 +89,7 @@ static int sdcard_get_space(unsigned long long *total, unsigned long long *avail static const char *sdcard_get_root(void) { - return SDCARD_PATH; + return tzplatform_mkpath(TZ_SYS_STORAGE, SDCARD_NODE); } static void sdcard_state_cb(keynode_t *key, void *data) -- 2.7.4 From bc401352acecfd4d112cac8d59acbbf9792db170 Mon Sep 17 00:00:00 2001 From: taeyoung Date: Fri, 11 Sep 2015 16:26:20 +0900 Subject: [PATCH 10/11] ringtones: change the path for the ringtones files Change-Id: I3b4d9d40bcf1fb86dd9db64c7b62034ad44293dd Signed-off-by: taeyoung --- src/storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage.c b/src/storage.c index 4ea9171..dcf301d 100644 --- a/src/storage.c +++ b/src/storage.c @@ -33,7 +33,7 @@ const char *dir_path[STORAGE_DIRECTORY_MAX] = { [STORAGE_DIRECTORY_MUSIC] = "Music", [STORAGE_DIRECTORY_DOCUMENTS] = "Documents", [STORAGE_DIRECTORY_OTHERS] = "Others", - [STORAGE_DIRECTORY_SYSTEM_RINGTONES] = "/opt/usr/share/settings/Ringtones", + [STORAGE_DIRECTORY_SYSTEM_RINGTONES] = "/usr/apps/org.tizen.setting/shared/res/settings/Ringtones", }; static dd_list *st_head; -- 2.7.4 From 41465ce5e41bb421b5178c62f7a99d886f40798a Mon Sep 17 00:00:00 2001 From: Taeyoung Kim Date: Mon, 3 Aug 2015 19:15:21 +0900 Subject: [PATCH 11/11] license: update license name Signed-off-by: Taeyoung Kim Change-Id: I18feb1e2e05f22c1142419998307ae09b9812eff --- packaging/libstorage.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libstorage.spec b/packaging/libstorage.spec index 501ed0d..f9eef1f 100644 --- a/packaging/libstorage.spec +++ b/packaging/libstorage.spec @@ -3,7 +3,7 @@ Summary: Library to get storage information Version: 0.1.0 Release: 0 Group: System/Libraries -License: Apache License, Version 2.0 +License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1: %{name}.manifest BuildRequires: cmake -- 2.7.4