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 <jy910.yun@samsung.com>
--- /dev/null
+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)
--- /dev/null
+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.
+
--- /dev/null
+/*
+ * 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 <storage.h> \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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 <stdio.h>
+
+#ifdef EINA_LIST
+#include <Eina.h>
+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 <glib.h>
+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
--- /dev/null
+/*
+ * 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 <dlog.h>
+#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
--- /dev/null
+/*
+ * 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 <tizen.h>
+
+/**
+ * @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
--- /dev/null
+/*
+ * 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 <sys/statvfs.h>
+#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
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+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
--- /dev/null
+[STORAGE]
+#reserved level check size 1GB
+CHECK_SIZE=1073741824
+#100MB
+RESERVE=104857600
+#5MB
+RESERVE_LITE=5242880
--- /dev/null
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/statvfs.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+#include <mntent.h>
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/statvfs.h>
+
+#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)
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/statvfs.h>
+#include <vconf.h>
+
+#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)
--- /dev/null
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#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;
+}
--- /dev/null
+# 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}