Refactor Preference API 85/252185/10
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 25 Jan 2021 08:18:05 +0000 (17:18 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 2 Feb 2021 06:50:13 +0000 (15:50 +0900)
Change-Id: I8d2d28dbdc046c0aa9becd3042fa6d71b89aa1be
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
43 files changed:
CMakeLists.txt
capi-appfw-preference.pc.in [deleted file]
cmake/Modules/ApplyPkgConfig.cmake [new file with mode: 0644]
include/app_preference_internal.h [deleted file]
include/app_preference_log.h [deleted file]
packaging/capi-appfw-preference.spec
preference/CMakeLists.txt [new file with mode: 0644]
preference/backend-interface.hh [new file with mode: 0644]
preference/capi-appfw-preference.pc.in [new file with mode: 0644]
preference/data-event-interface.hh [new file with mode: 0644]
preference/data-internal.cc [new file with mode: 0644]
preference/data-internal.hh [new file with mode: 0644]
preference/file-backend-internal.cc [new file with mode: 0644]
preference/file-backend-internal.hh [new file with mode: 0644]
preference/file-internal.cc [new file with mode: 0644]
preference/file-internal.hh [new file with mode: 0644]
preference/log-internal.hh [new file with mode: 0644]
preference/path-internal.cc [new file with mode: 0644]
preference/path-internal.hh [new file with mode: 0644]
preference/preference-internal.cc [new file with mode: 0644]
preference/preference-internal.hh [new file with mode: 0644]
preference/stub.cc [new file with mode: 0644]
src/CMakeLists.txt [deleted file]
src/preference.c [deleted file]
src/preference_db.c [deleted file]
src/preference_inoti.c [deleted file]
src/tool/CMakeLists.txt [deleted file]
src/tool/pref_dump.sh [deleted file]
src/tool/preference_tool.c [deleted file]
tool/CMakeLists.txt [new file with mode: 0644]
tool/log-private.hh [new file with mode: 0644]
tool/pref_dump.sh [new file with mode: 0644]
tool/preference_tool.cc [new file with mode: 0644]
unittests/CMakeLists.txt
unittests/main.cc [new file with mode: 0644]
unittests/mock/common_mock.cc
unittests/mock/common_mock.h
unittests/mock/mock_hook.h
unittests/mock/module_mock.h
unittests/mock/test_fixture.cc
unittests/mock/test_fixture.h
unittests/preference_test.cc
unittests/preference_unittest.cc [new file with mode: 0644]

index 919c4a32bcc344af859a6398be629c769dc69965..6d194f43239838824ee8f520f72719350db96a06 100644 (file)
@@ -1,14 +1,53 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 
-SET(INC_DIR include)
+PROJECT(capi-appfw-preference C CXX)
 
-ADD_SUBDIRECTORY(src)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCDIR "\${prefix}/include")
+SET(EXEC_PREFIX "\${prefix}")
 
-INSTALL(
-        DIRECTORY ${INC_DIR}/ DESTINATION include/appfw
-        FILES_MATCHING
-        PATTERN "*_private.h" EXCLUDE
-        PATTERN "${INC_DIR}/*.h"
-        )
+## Compile flags
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-zdefs -fvisibility=hidden -g -Wall -Werror -fpic")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
 
-ADD_SUBDIRECTORY(unittests)
\ No newline at end of file
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} -std=c++14")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
+
+## Target
+SET(TARGET_PREFERENCE "capi-appfw-preference")
+SET(TARGET_TOOL "preference_tool")
+
+ENABLE_TESTING()
+SET(TARGET_UNIT_TESTS "preference-unit-tests")
+
+INCLUDE(FindPkgConfig)
+INCLUDE(ApplyPkgConfig)
+
+PKG_CHECK_MODULES(CAPI_APPFW_APP_COMMON_DEPS REQUIRED capi-appfw-app-common)
+PKG_CHECK_MODULES(CAPI_BASE_COMMON_DEPS REQUIRED capi-base-common)
+PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
+PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
+PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(LIBTZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
+PKG_CHECK_MODULES(SQLITE3_DEPS REQUIRED sqlite3)
+PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info)
+
+INSTALL(DIRECTORY include/
+  DESTINATION include/appfw
+  FILES_MATCHING
+  PATTERN "*_private.h" EXCLUDE
+  PATTERN "include/*.h"
+)
+
+ADD_SUBDIRECTORY(preference)
+ADD_SUBDIRECTORY(tool)
+ADD_SUBDIRECTORY(unittests)
diff --git a/capi-appfw-preference.pc.in b/capi-appfw-preference.pc.in
deleted file mode 100644 (file)
index f4504d4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# Package Information for pkg-config
-
-prefix=@PREFIX@
-exec_prefix=/usr
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDE_INSTALL_DIR@/appfw
-
-Name: @PC_NAME@
-Description: @PACKAGE_DESCRIPTION@
-Version: @VERSION@
-Requires: @PC_REQUIRED@
-Libs: -L${libdir} @PC_LDFLAGS@
-Cflags: -I${includedir}
diff --git a/cmake/Modules/ApplyPkgConfig.cmake b/cmake/Modules/ApplyPkgConfig.cmake
new file mode 100644 (file)
index 0000000..9b84be3
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#
+# This function applies external (out of source tree) dependencies
+# to given target. Arguments are:
+#   TARGET - valid cmake target
+#   PRIVACY - dependency can be inherited by dependent targets or not:
+#     PUBLIC - this should be used by default, cause compile/link flags passing
+#     PRIVATE - do not passes any settings to dependent targets,
+#               may be usefull for static libraries from the inside of the project
+# Argument ARGV2 and following are supposed to be names of checked pkg config
+# packages. This function will use variables created by check_pkg_modules().
+#  - ${DEP_NAME}_LIBRARIES
+#  - ${DEP_NAME}_INCLUDE_DIRS
+#  - ${DEP_NAME}_CFLAGS
+#
+FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+  MATH(EXPR DEST_INDEX "${ARGC}-1")
+  FOREACH(I RANGE 2 ${DEST_INDEX})
+    IF(NOT ${ARGV${I}}_FOUND)
+      MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND")
+    ENDIF(NOT ${ARGV${I}}_FOUND)
+    TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}")
+    TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}")
+    STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}")
+    SET(CFLAGS_LIST ${CFLAGS_STR})
+    SEPARATE_ARGUMENTS(CFLAGS_LIST)
+    FOREACH(OPTION ${CFLAGS_LIST})
+      TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION})
+    ENDFOREACH(OPTION)
+    SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true)
+  ENDFOREACH(I RANGE 2 ${DEST_INDEX})
+ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
diff --git a/include/app_preference_internal.h b/include/app_preference_internal.h
deleted file mode 100644 (file)
index 0221c20..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2011 - 2016 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_APPFW_PREFERENCE_INTERNAL_H__
-#define __TIZEN_APPFW_PREFERENCE_INTERNAL_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "app_preference_log.h"
-#include "linux/limits.h"
-
-#define BUF_LEN                        (4096)
-#define PREF_DIR       ".pref/"
-
-#define PREFERENCE_KEY_PATH_LEN        1024
-#define ERR_LEN                        1024
-
-#define PREF_DB_NAME           ".pref.db"
-#define PREF_TBL_NAME          "pref"
-#define PREF_F_KEY_NAME                "pref_key"
-#define PREF_F_TYPE_NAME       "pref_type"
-#define PREF_F_DATA_NAME       "pref_data"
-
-/* ASCII VALUE */
-#define PREF_KEYNAME_C_PAD '='
-#define PREF_KEYNAME_C_PLUS '+'
-#define PREF_KEYNAME_C_SLASH '/'
-
-#define PREF_KEYNAME_C_DOT '.'
-#define PREF_KEYNAME_C_UNDERSCORE '_'
-#define PREF_KEYNAME_C_HYPHEN '-'
-
-/**
- * @brief Definition for PREFERENCE_ERROR_WRONG_PREFIX.
- */
-#define PREFERENCE_ERROR_WRONG_PREFIX    -2
-
-/**
- * @brief Definition for PREFERENCE_ERROR_WRONG_TYPE.
- */
-#define PREFERENCE_ERROR_WRONG_TYPE      -3
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_OPEN.
- */
-#define PREFERENCE_ERROR_FILE_OPEN       -21
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_FREAD.
- */
-#define PREFERENCE_ERROR_FILE_FREAD      -22
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_FGETS.
- */
-#define PREFERENCE_ERROR_FILE_FGETS      -23
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_WRITE.
- */
-#define PREFERENCE_ERROR_FILE_WRITE      -24
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_SYNC.
- */
-#define PREFERENCE_ERROR_FILE_SYNC       -25
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_CHMOD.
- */
-#define PREFERENCE_ERROR_FILE_CHMOD      -28
-
-/**
- * @brief Definition for PREFERENCE_ERROR_FILE_LOCK.
- */
-#define PREFERENCE_ERROR_FILE_LOCK       -29
-
-typedef struct _pref_changed_cb_node_t {
-       char *key;
-       preference_changed_cb cb;
-       void *user_data;
-       struct _pref_changed_cb_node_t *prev;
-       struct _pref_changed_cb_node_t *next;
-} pref_changed_cb_node_t;
-
-typedef struct _keynode_t {
-       char *keyname;                  /**< Keyname for keynode */
-       int type;                       /**< Keynode type */
-       union {
-               int i;                  /**< Integer type */
-               int b;                  /**< Bool type */
-               double d;               /**< Double type */
-               char *s;                /**< String type */
-       } value;                        /**< Value for keynode */
-       struct _keynode_t *next;        /**< Next keynode */
-} keynode_t;
-
-/**
- * @brief The structure type for opaque type. It must be used via accessor functions.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
- */
-typedef struct _keylist_t {
-       int num;                /**< Number of list */
-       keynode_t *head;        /**< Head node */
-       keynode_t *cursor;      /**< Cursor node */
-} keylist_t;
-
-
-int _preference_kdb_add_notify
-       (keynode_t *keynode, preference_changed_cb cb, void *data);
-int _preference_kdb_del_notify
-       (keynode_t *keynode);
-
-int _preference_get_key_path(keynode_t *keynode, char *path);
-int _preference_get_key(keynode_t *keynode);
-
-int _preference_keynode_set_keyname(keynode_t *keynode, const char *keyname);
-__attribute__ ((gnu_inline)) inline keynode_t *_preference_keynode_new(void);
-__attribute__ ((gnu_inline)) inline void _preference_keynode_free(keynode_t *keynode);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TIZEN_APPFW_PREFERENCE_INTERNAL_H__ */
-
diff --git a/include/app_preference_log.h b/include/app_preference_log.h
deleted file mode 100644 (file)
index 5aa8144..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015 - 2016 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.
- */
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "CAPI_APPFW_APPLICATION_PREFERENCE"
-#define DBG_MODE (1)
-
-#ifndef __PREFERENCE_LOG_H__
-#define __PREFERENCE_LOG_H__
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <dlog.h>
-
-
-#define INFO(fmt, arg...)
-#define DBG(fmt, arg...) SECURE_SLOGI(fmt, ##arg)
-#define ERR(fmt, arg...) LOGE(fmt, ##arg)
-#define SECURE_ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg)
-#define FATAL(fmt, arg...) SECURE_SLOGF(fmt, ##arg)
-#define WARN(fmt, arg...) SECURE_SLOGW(fmt, ##arg)
-
-
-/************** Return ***************/
-#define ret_if(expr) \
-       do { \
-               if (expr) { \
-                       ERR("(%s) -> %s() return", #expr, __FUNCTION__); \
-                       return; \
-               } \
-       } while (0)
-#define retv_if(expr, val) \
-       do { \
-               if (expr) { \
-                       ERR("(%s) -> %s() return", #expr, __FUNCTION__); \
-                       return (val); \
-               } \
-       } while (0)
-#define retm_if(expr, fmt, arg...) \
-       do { \
-               if (expr) { \
-                       ERR(fmt, ##arg); \
-                       return; \
-               } \
-       } while (0)
-#define retvm_if(expr, val, fmt, arg...) \
-       do { \
-               if (expr) { \
-                       ERR(fmt, ##arg); \
-                       return (val); \
-               } \
-       } while (0)
-#define retex_if(expr, fmt, arg...) \
-       do { \
-               if (expr) { \
-                       ERR(fmt, ##arg); \
-                       goto CATCH; \
-               } \
-       } while (0)
-
-
-/************** TimeCheck ***************/
-#ifdef PREFERENCE_TIMECHECK
-#define START_TIME_CHECK \
-       init_time();\
-       startT = set_start_time();
-#define END_TIME_CHECK \
-       PREFERENCE_DEBUG("time = %f ms\n", exec_time(startT));
-#else
-#define START_TIME_CHECK
-#define END_TIME_CHECK
-#endif
-
-
-#endif                         /* __PREFERENCE_LOG_H__ */
-
index 800a9adfb2d68cccff5d2efcfa5a3cb8d9ff339d..c9617fd23c140da2ad88a2a8f8fdd2b114f2e718 100644 (file)
@@ -14,6 +14,7 @@ BuildRequires:  pkgconfig(gmock)
 BuildRequires:  pkgconfig(capi-appfw-app-common)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(pkgmgr-info)
 %if 0%{?gcov:1}
 BuildRequires:  lcov
 BuildRequires:  zip
@@ -71,7 +72,7 @@ install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
 
 %check
 cd unittests
-LD_LIBRARY_PATH=../src ctest -V
+LD_LIBRARY_PATH=../preference ctest -V
 %if 0%{?gcov:1}
 cd ../src
 lcov -c --ignore-errors graph --no-external -d . -o preference.info
@@ -88,13 +89,12 @@ install -m 0644 preference.zip %{buildroot}%{_datadir}/gcov/
 %{_libdir}/libcapi-appfw-preference.so.*
 %attr(0700,root,root) %{_bindir}/preference_tool
 %attr(755,root,root) /opt/etc/dump.d/module.d/pref_dump.sh
+%attr(755,root,root) %{_bindir}/preference-unit-tests
 %license LICENSE
 
 %files devel
 %manifest %{name}.manifest
 %{_includedir}/appfw/app_preference.h
-%{_includedir}/appfw/app_preference_internal.h
-%{_includedir}/appfw/app_preference_log.h
 %{_libdir}/pkgconfig/capi-appfw-preference.pc
 %{_libdir}/libcapi-appfw-preference.so
 
diff --git a/preference/CMakeLists.txt b/preference/CMakeLists.txt
new file mode 100644 (file)
index 0000000..68e0318
--- /dev/null
@@ -0,0 +1,33 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} PREFERENCE_SRCS)
+
+ADD_LIBRARY(${TARGET_PREFERENCE} SHARED ${PREFERENCE_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_PREFERENCE} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_PREFERENCE} PROPERTIES VERSION ${FULLVER})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_PREFERENCE} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../include/)
+
+APPLY_PKG_CONFIG(${TARGET_PREFERENCE} PUBLIC
+  CAPI_APPFW_APP_COMMON_DEPS
+  CAPI_BASE_COMMON_DEPS
+  DLOG_DEPS
+  GLIB_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_PREFERENCE}
+  DESTINATION ${LIBDIR}
+  COMPONENT RuntimeLibraries
+)
+
+SET(PC_NAME ${TARGET_PREFERENCE})
+SET(PC_REQUIRED "capi-base-common")
+SET(PC_LD_FLAGS -l${TARGET_PREFERENCE})
+
+# pkg-config file
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/capi-appfw-preference.pc.in
+  ${CMAKE_CURRENT_SOURCE_DIR}/capi-appfw-preference.pc @ONLY)
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/capi-appfw-preference.pc
+  DESTINATION ${LIBDIR}/pkgconfig)
diff --git a/preference/backend-interface.hh b/preference/backend-interface.hh
new file mode 100644 (file)
index 0000000..f533307
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_BACKEND_INTERFACE_HH_
+#define PREFERENCE_BACKEND_INTERFACE_HH_
+
+#include <vector>
+#include <memory>
+#include <string>
+
+#include "preference/data-event-interface.hh"
+#include "preference/data-internal.hh"
+
+namespace preference {
+namespace internal {
+
+class IBackend {
+ public:
+  virtual ~IBackend() { }
+
+  virtual int Set(const Data& data) = 0;
+  virtual std::shared_ptr<Data> Get(const std::string& key) = 0;
+  virtual int Remove(const std::string& key) = 0;
+  virtual int RemoveAll() = 0;
+  virtual int AddWatch(const std::string& key, IDataEvent* listener) = 0;
+  virtual int RemoveWatch(const std::string& key) = 0;
+  virtual std::vector<std::string> GetKeys() = 0;
+  virtual bool IsExisting(const std::string& key) = 0;
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_BACKEND_INTERFACE_HH_
diff --git a/preference/capi-appfw-preference.pc.in b/preference/capi-appfw-preference.pc.in
new file mode 100644 (file)
index 0000000..f4504d4
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@/appfw
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
diff --git a/preference/data-event-interface.hh b/preference/data-event-interface.hh
new file mode 100644 (file)
index 0000000..42e712e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_DATA_EVENT_INTERFACE_HH_
+#define PREFERENCE_DATA_EVENT_INTERFACE_HH_
+
+#include <string>
+
+namespace preference {
+namespace internal {
+
+class IDataEvent {
+ public:
+  virtual ~IDataEvent() { }
+
+  virtual void OnDataCreated(const std::string& key) = 0;
+  virtual void OnDataUpdated(const std::string& key) = 0;
+  virtual void OnDataDeleted(const std::string& key) = 0;
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_DATA_EVENT_INTERFACE_HH_
diff --git a/preference/data-internal.cc b/preference/data-internal.cc
new file mode 100644 (file)
index 0000000..15bbaa3
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2021 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 <cstring>
+
+#include "preference/data-internal.hh"
+
+namespace preference {
+namespace internal {
+
+Data::Data(std::string key) : key_(std::move(key)) {
+}
+
+const std::string& Data::GetKey() const {
+  return key_;
+}
+
+void Data::SetString(const char* str) {
+  size_t len = std::strlen(str) + 1;
+  value_.clear();
+  std::copy(str, str + len, std::back_inserter(value_));
+  SetType<const char*>(str);
+}
+
+void Data::SetInt(int i) {
+  Set<int>(i);
+  SetType<int>(i);
+}
+
+void Data::SetDouble(double d) {
+  Set<double>(d);
+  SetType<double>(d);
+}
+
+void Data::SetBoolean(bool b) {
+  Set<bool>(b);
+  SetType<bool>(b);
+}
+
+const char* Data::GetString() const {
+  const char* str = reinterpret_cast<const char*>(&value_[0]);
+  return str;
+}
+
+int Data::GetInt() const {
+  return Get<int>();
+}
+
+double Data::GetDouble() const {
+  return Get<double>();
+}
+
+bool Data::GetBoolean() const {
+  return Get<bool>();
+}
+
+const Data::Type Data::GetType() const {
+  return type_;
+}
+
+}  // namespace internal
+}  // namespace preference
diff --git a/preference/data-internal.hh b/preference/data-internal.hh
new file mode 100644 (file)
index 0000000..0cd70fb
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_DATA_INTERNAL_HH_
+#define PREFERENCE_DATA_INTERNAL_HH_
+
+#include <string>
+#include <typeinfo>
+#include <vector>
+
+namespace preference {
+namespace internal {
+
+class Data {
+ public:
+  enum class Type : int {
+   NONE = 0,
+   STRING,
+   INT,
+   DOUBLE,
+   BOOLEAN,
+  };
+
+  Data(std::string key);
+  ~Data() = default;
+
+  const std::string& GetKey() const;
+  void SetString(const char* value);
+  void SetInt(int value);
+  void SetDouble(double value);
+  void SetBoolean(bool value);
+  const char* GetString() const;
+  int GetInt() const;
+  double GetDouble() const;
+  bool GetBoolean() const;
+  const Type GetType() const;
+
+  const std::vector<uint8_t>& GetRaw() const {
+    return value_;
+  }
+
+ private:
+  template<typename T>
+  void SetType(T d) {
+    if (typeid(T) == typeid(const char*))
+      type_ = Type::STRING;
+    else if (typeid(T) == typeid(int))
+      type_ = Type::INT;
+    else if (typeid(T) == typeid(double))
+      type_ = Type::DOUBLE;
+    else if (typeid(T) == typeid(bool))
+      type_ = Type::BOOLEAN;
+    else
+      type_ = Type::NONE;
+  }
+
+  template<typename T>
+  void Set(T d) {
+    value_.clear();
+    uint8_t* p = reinterpret_cast<uint8_t*>(&d);
+    std::copy(p, p + sizeof(T), std::back_inserter(value_));
+  }
+
+  template<typename T>
+  T Get() const {
+    T d;
+    uint8_t* p = reinterpret_cast<uint8_t*>(&d);
+    std::copy(value_.begin(), value_.begin() + sizeof(T), p);
+    return d;
+  }
+
+ private:
+  std::string key_;
+  std::vector<uint8_t> value_;
+  Type type_ = Type::NONE;
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_DATA_INTERNAL_HH_
diff --git a/preference/file-backend-internal.cc b/preference/file-backend-internal.cc
new file mode 100644 (file)
index 0000000..b487da8
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2021 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 <errno.h>
+#include <sys/inotify.h>
+
+#include "preference/file-backend-internal.hh"
+#include "preference/file-internal.hh"
+#include "preference/log-internal.hh"
+#include "preference/path-internal.hh"
+
+namespace preference {
+namespace internal {
+
+FileBackend::FileBackend() {
+}
+
+FileBackend::~FileBackend() {
+  RemoveWatch();
+}
+
+int FileBackend::Set(const Data& data) {
+  File file(data.GetKey(), false);
+  file.SetData(data);
+  return file.Write();
+}
+
+std::shared_ptr<Data> FileBackend::Get(const std::string& key) {
+  File file(key, false);
+  if (file.Read() < 0)
+    return nullptr;
+
+  return std::make_shared<Data>(file.GetData());
+}
+
+int FileBackend::Remove(const std::string& key) {
+  File file(key, false);
+  return file.Delete();
+}
+
+int FileBackend::RemoveAll() {
+  DIR* dir = opendir(Path::Get().c_str());
+  if (dir == nullptr) {
+    _E("Failed to open directory. errno(%d)", errno);
+    return -1;
+  }
+
+  int ret = 0;
+  int retry_count = 7;
+  struct dirent* entry;
+  while ((entry = readdir(dir)) != nullptr) {
+    if (entry->d_name[0] == '.')
+      continue;
+
+    do {
+      File file(entry->d_name, true);
+      if (file.Delete() < 0) {
+        _E("Failed to delete file. errno(%d)", errno);
+        ret = -1;
+      } else {
+        ret = 0;
+        break;
+      }
+    } while (retry_count--);
+    retry_count = 7;
+  }
+  closedir(dir);
+  return ret;
+}
+
+int FileBackend::AddWatch(const std::string& key, IDataEvent* listener) {
+  if (AddWatch() < 0)
+    return -1;
+
+  File file(key);
+  key_map_[file.GetName()] = key;
+  watch_map_[file.GetName()] = listener;
+  return 0;
+}
+
+int FileBackend::RemoveWatch(const std::string& key) {
+  File file(key);
+  auto i = key_map_.find(file.GetName());
+  if (i == key_map_.end())
+    return -1;
+
+  key_map_.erase(file.GetName());
+  watch_map_.erase(file.GetName());
+  return 0;
+}
+
+std::vector<std::string> FileBackend::GetKeys() {
+  std::vector<std::string> keys;
+  DIR* dir = opendir(Path::Get().c_str());
+  if (dir == nullptr) {
+    _E("Failed to open directory. errno(%d)", errno);
+    return {};
+  }
+
+  struct dirent* entry;
+  while ((entry = readdir(dir)) != nullptr) {
+    if (entry->d_name[0] == '.')
+      continue;
+
+    auto key = GetKey(entry->d_name);
+    if (key.empty())
+      continue;
+
+    keys.push_back(key);
+  }
+  closedir(dir);
+
+  return keys;
+}
+
+bool FileBackend::IsExisting(const std::string& key) {
+  File file(key, false);
+  return file.IsExisting();
+}
+
+int FileBackend::AddWatch() {
+  if (tag_ != 0)
+    return 0;
+
+  fd_ = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  if (fd_ < 0) {
+    _E("Failed to initilaize inotify. errno(%d)", errno);
+    return -1;
+  }
+
+  wd_ = inotify_add_watch(fd_, Path::Get().c_str(),
+      (IN_CREATE | IN_CLOSE_WRITE | IN_DELETE));
+  if (wd_ < 0) {
+    _E("Failed to add watch. errno(%d)", errno);
+    RemoveWatch();
+    return -1;
+  }
+
+  channel_ = g_io_channel_unix_new(fd_);
+  if (channel_ == nullptr) {
+    _E("Failed to create GIO channel");
+    RemoveWatch();
+    return -1;
+  }
+
+  tag_ = g_io_add_watch(channel_, G_IO_IN, GIOFunc, this);
+  if (tag_ == 0) {
+    _E("Failed to add watch");
+    RemoveWatch();
+    return -1;
+  }
+
+  return 0;
+}
+
+void FileBackend::RemoveWatch() {
+  if (tag_) {
+    g_source_remove(tag_);
+    tag_ = 0;
+  }
+
+  if (channel_) {
+    g_io_channel_unref(channel_);
+    channel_ = nullptr;
+  }
+
+  if (wd_ > 0) {
+    inotify_rm_watch(fd_, wd_);
+    wd_ = 0;
+  }
+
+  if (fd_ > 0) {
+    close(fd_);
+    fd_ = 0;
+  }
+}
+
+gboolean FileBackend::GIOFunc(GIOChannel* channel, GIOCondition cond,
+    gpointer user_data) {
+  FileBackend* backend = static_cast<FileBackend*>(user_data);
+  char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event))));
+  char* ptr;
+  ssize_t len;
+  struct inotify_event* event;
+
+  int fd = g_io_channel_unix_get_fd(channel);
+  while ((len = read(fd, buf, sizeof(buf))) > 0) {
+    for (ptr = buf; ptr < buf + len;
+         ptr += sizeof(struct inotify_event) + event->len) {
+      event = reinterpret_cast<struct inotify_event*>(ptr);
+      char* nptr = ptr + sizeof(struct inotify_event) + event->len;
+      if (nptr > buf + len)
+        break;
+
+      if (event->len) {
+        if (event->mask & IN_CREATE) {
+          auto i = backend->watch_map_.find(event->name);
+          if (i != backend->watch_map_.end())
+            i->second->OnDataCreated(backend->key_map_[event->name]);
+        } else if (event->mask & IN_CLOSE_WRITE) {
+          auto i = backend->watch_map_.find(event->name);
+          if (i != backend->watch_map_.end())
+            i->second->OnDataUpdated(backend->key_map_[event->name]);
+        } else if (event->mask & IN_DELETE) {
+          auto i = backend->watch_map_.find(event->name);
+          if (i != backend->watch_map_.end())
+            i->second->OnDataDeleted(backend->key_map_[event->name]);
+        }
+      }
+    }
+  }
+
+  return G_SOURCE_CONTINUE;
+}
+
+std::string FileBackend::GetKey(const std::string& file_name) {
+  File file(file_name, true);
+  if (file.Read() < 0)
+    return std::string("");
+
+  auto data = file.GetData();
+  return data.GetKey();
+}
+
+}  // namespace internal
+}  // namespace preference
diff --git a/preference/file-backend-internal.hh b/preference/file-backend-internal.hh
new file mode 100644 (file)
index 0000000..53f53f4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_FILE_BACKEND_INTERNAL_HH_
+#define PREFERENCE_FILE_BACKEND_INTERNAL_HH_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <map>
+
+#include "preference/backend-interface.hh"
+
+namespace preference {
+namespace internal {
+
+class FileBackend : public IBackend {
+ public:
+  FileBackend();
+  virtual ~FileBackend();
+
+  int Set(const Data& data) override;
+  std::shared_ptr<Data> Get(const std::string& key) override;
+  int Remove(const std::string& key) override;
+  int RemoveAll() override;
+  int AddWatch(const std::string& key, IDataEvent* listener) override;
+  int RemoveWatch(const std::string& key) override;
+  std::vector<std::string> GetKeys() override;
+  bool IsExisting(const std::string& key) override;
+
+ private:
+  std::string GetKey(const std::string& file_name);
+  static gboolean GIOFunc(GIOChannel* channel, GIOCondition cond,
+      gpointer user_data);
+  int AddWatch();
+  void RemoveWatch();
+
+ private:
+  int fd_ = -1;
+  int wd_ = -1;
+  GIOChannel* channel_ = nullptr;
+  guint tag_ = 0;
+  std::map<std::string, std::string> key_map_;
+  std::map<std::string, IDataEvent*> watch_map_;
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_FILE_BACKEND_INTERNAL_HH_
diff --git a/preference/file-internal.cc b/preference/file-internal.cc
new file mode 100644 (file)
index 0000000..dd653ca
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2021 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 <errno.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "preference/file-internal.hh"
+#include "preference/log-internal.hh"
+#include "preference/path-internal.hh"
+
+namespace preference {
+namespace internal {
+namespace {
+
+const int RETRY_COUNT = 7;
+const int RETRY_SLEEP_UTIME = 10000;
+
+}  // namespace
+
+File::File(std::string name, bool is_checksum) {
+  if (!is_checksum) {
+    char* checksum = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
+        name.c_str(), name.length());
+    name_ = std::string(checksum);
+    g_free(checksum);
+  } else {
+    name_ = std::move(name);
+  }
+  path_ = Path::Get(name_);
+}
+
+File::File(std::string name, std::string pref_path, bool is_checksum) {
+  if (!is_checksum) {
+    char* checksum = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
+        name.c_str(), name.length());
+    name_ = std::string(checksum);
+    g_free(checksum);
+  } else {
+    name_ = std::move(name);
+  }
+  path_ = pref_path + "/" + name_;
+}
+
+File::~File() {
+  Close();
+}
+
+void File::SetData(const Data& data) {
+  raw_data_.clear();
+
+  int key_length = data.GetKey().length();
+  uint8_t* p = reinterpret_cast<uint8_t*>(&key_length);
+  std::copy(p, p + sizeof(int), std::back_inserter(raw_data_));
+
+  std::copy(data.GetKey().begin(), data.GetKey().end(),
+      std::back_inserter(raw_data_));
+
+  int type = static_cast<int>(data.GetType());
+  p = reinterpret_cast<uint8_t*>(&type);
+  std::copy(p, p + sizeof(int), std::back_inserter(raw_data_));
+
+  std::copy(data.GetRaw().begin(), data.GetRaw().end(),
+      std::back_inserter(raw_data_));
+}
+
+Data File::GetData() {
+  int index = 0;
+  int key_length = 0;
+  uint8_t* p = reinterpret_cast<uint8_t*>(&key_length);
+  std::copy(&raw_data_[index], &raw_data_[index] + sizeof(int), p);
+  index += sizeof(int);
+
+  std::string key;
+  std::copy(&raw_data_[index], &raw_data_[index] + key_length,
+      std::back_inserter(key));
+  index += key_length;
+
+  int type = 0;
+  p = reinterpret_cast<uint8_t*>(&type);
+  std::copy(&raw_data_[index], &raw_data_[index] + sizeof(int), p);
+  index += sizeof(int);
+
+  Data data(key);
+
+  Data::Type data_type = static_cast<Data::Type>(type);
+  if (data_type == Data::Type::STRING) {
+    const char* str = reinterpret_cast<const char*>(&raw_data_[index]);
+    data.SetString(str);
+  } else if (data_type == Data::Type::INT) {
+    int i = 0;
+    p = reinterpret_cast<uint8_t*>(&i);
+    std::copy(&raw_data_[index], &raw_data_[index] + sizeof(int), p);
+    data.SetInt(i);
+  } else if (data_type == Data::Type::DOUBLE) {
+    double d = 0;
+    p = reinterpret_cast<uint8_t*>(&d);
+    std::copy(&raw_data_[index], &raw_data_[index] + sizeof(double), p);
+    data.SetDouble(d);
+  } else if (data_type == Data::Type::BOOLEAN) {
+    bool b = 0;
+    p = reinterpret_cast<uint8_t*>(&b);
+    std::copy(&raw_data_[index], &raw_data_[index] + sizeof(bool), p);
+    data.SetBoolean(b);
+  }
+
+  return data;
+}
+
+int File::Write() {
+  int retry_count = 0;
+  int ret = TryWrite();
+  while (ret != 0 && retry_count < RETRY_COUNT) {
+    retry_count++;
+    usleep(retry_count * RETRY_SLEEP_UTIME);
+    ret = TryWrite();
+  }
+
+  return ret;
+}
+
+int File::Read() {
+  int retry_count = 0;
+  int ret = TryRead();
+  while (ret != 0 && retry_count < RETRY_COUNT) {
+    retry_count++;
+    usleep(retry_count * RETRY_SLEEP_UTIME);
+    ret = TryRead();
+  }
+
+  return ret;
+}
+
+int File::Delete() {
+  int retry_count = 0;
+  int ret = TryDelete();
+  while (ret != 0 && retry_count < RETRY_COUNT) {
+    retry_count++;
+    usleep(retry_count * RETRY_SLEEP_UTIME);
+    ret = TryDelete();
+  }
+
+  return ret;
+}
+
+bool File::IsExisting() {
+  if (access(path_.c_str(), F_OK) == 0)
+    return true;
+
+  return false;
+}
+
+int File::Open(bool readonly) {
+  if (readonly)
+    fd_ = open(path_.c_str(), O_RDONLY);
+  else
+    fd_ = open(path_.c_str(), (O_CREAT | O_WRONLY | O_TRUNC), 0644);
+  if (fd_ < 0) {
+    _E("Failed to open %s. errno(%d)", path_.c_str(), errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+void File::Close() {
+  if (fd_ > 0) {
+    close(fd_);
+    fd_ = 0;
+  }
+}
+
+int File::Sync() {
+  int ret = fdatasync(fd_);
+  if (ret < 0) {
+    _E("Failed to synchronize a file. errno(%d)", errno);
+    return static_cast<int>(Error::ERROR_FILE_SYNC);
+  }
+
+  return 0;
+}
+
+bool File::Lock(bool readonly) {
+  struct flock lock;
+
+  lock.l_type = readonly ? F_RDLCK : F_WRLCK;
+  lock.l_start = 0;
+  lock.l_whence = SEEK_SET;
+  lock.l_len = 0;
+
+  if (fcntl(fd_, F_SETLK, &lock) < 0)
+    return false;
+
+  return true;
+}
+
+void File::Unlock() {
+  struct flock lock;
+
+  lock.l_type = F_UNLCK;
+  lock.l_start = 0;
+  lock.l_whence = SEEK_SET;
+  lock.l_len = 0;
+
+  fcntl(fd_, F_SETLK, &lock);
+}
+
+int File::TryWrite() {
+  int ret = Open(false);
+  if (ret < 0)
+    return static_cast<int>(Error::ERROR_FILE_OPEN);
+
+  if (!Lock(false)) {
+    Close();
+    return static_cast<int>(Error::ERROR_FILE_LOCK);
+  }
+
+  ssize_t bytes_written;
+  ssize_t size = raw_data_.size();
+  uint8_t* buffer = static_cast<uint8_t*>(&raw_data_[0]);
+
+  bytes_written = write(fd_, buffer, size);
+  if (bytes_written <= 0) {
+    _E("Failed to write to a fd(%d). errno(%d)", fd_, errno);
+    ret = static_cast<int>(Error::ERROR_FILE_WRITE);
+  } else {
+    ret = Sync();
+  }
+
+  Unlock();
+  Close();
+  return ret;
+}
+
+int File::TryRead() {
+  int ret = Open();
+  if (ret < 0)
+    return static_cast<int>(Error::ERROR_FILE_OPEN);
+
+  if (!Lock()) {
+    Close();
+    return static_cast<int>(Error::ERROR_FILE_LOCK);
+  }
+
+  ssize_t total_size = 0;
+  ssize_t bytes_read;
+  uint8_t buffer[4096] = { 0, };
+
+  raw_data_.clear();
+  while ((bytes_read = read(fd_, buffer, sizeof(buffer))) > 0) {
+    std::copy(buffer, buffer + bytes_read, std::back_inserter(raw_data_));
+    total_size += bytes_read;
+  }
+
+  if (total_size == 0) {
+    _E("Total size is zero");
+    ret = static_cast<int>(Error::ERROR_FILE_READ);
+  }
+
+  Unlock();
+  Close();
+  return ret;
+}
+
+int File::TryDelete() {
+  int ret = unlink(path_.c_str());
+  if (ret != 0) {
+    _E("Failed to delete %s. errno(%d)", path_.c_str(), errno);
+    return -1;
+  }
+  return 0;
+}
+
+}  // namespace internal
+}  // namespace preference
diff --git a/preference/file-internal.hh b/preference/file-internal.hh
new file mode 100644 (file)
index 0000000..0386cec
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_FILE_INTERNAL_HH_
+#define PREFERENCE_FILE_INTERNAL_HH_
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "preference/data-internal.hh"
+
+namespace preference {
+namespace internal {
+
+class File {
+ public:
+  enum class Error : int {
+    ERROR_WRONG_PREFIX = -2,
+    ERROR_WRONG_TYPE = -3,
+    ERROR_FILE_OPEN = -21,
+    ERROR_FILE_READ = -22,
+    ERROR_FILE_WRITE = -23,
+    ERROR_FILE_SYNC = -24,
+    ERROR_FILE_CHMOD = -25,
+    ERROR_FILE_LOCK = -26,
+  };
+
+  File(std::string name, bool is_checksum = false);
+  File(std::string name, std::string pref_path, bool is_checksum = false);
+  ~File();
+
+  const std::string& GetName() {
+    return name_;
+  }
+
+  const std::string& GetPath() {
+    return path_;
+  }
+
+  void SetData(const Data& data);
+  Data GetData();
+
+  int Write();
+  int Read();
+  int Delete();
+  bool IsExisting();
+  void Close();
+
+ private:
+  int Open(bool readonly = true);
+  int Sync();
+  bool Lock(bool readonly = true);
+  void Unlock();
+  int TryWrite();
+  int TryRead();
+  int TryDelete();
+
+ private:
+  std::string name_;
+  std::string path_;
+  std::vector<uint8_t> raw_data_;
+  int fd_ = 0;
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_FILE_INTERNAL_HH_
diff --git a/preference/log-internal.hh b/preference/log-internal.hh
new file mode 100644 (file)
index 0000000..4f8bb9a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_LOG_INTERNAL_HH_
+#define PREFERENCE_LOG_INTERNAL_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "CAPI_APPFW_PREFERENCE"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // PREFERENCE_LOG_INTERNAL_HH_
diff --git a/preference/path-internal.cc b/preference/path-internal.cc
new file mode 100644 (file)
index 0000000..d6c63e8
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 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 <app_common.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "preference/log-internal.hh"
+#include "preference/path-internal.hh"
+
+namespace preference {
+namespace internal {
+
+std::string Path::Get() {
+  static std::string path;
+  if (!path.empty())
+    return path;
+
+  char* data_path = app_get_data_path();
+  if (data_path != nullptr) {
+    path = std::string(data_path) + ".pref/";
+    free(data_path);
+  } else {
+    path = "/tmp/." + std::to_string(getpid()) + "_pref/";
+  }
+
+  if (access(path.c_str(), F_OK) != 0) {
+    int ret = mkdir(path.c_str(),
+        (S_IRWXU | S_IRGRP | S_IXGRP | S_ISGID | S_IROTH | S_IXOTH));
+    if (ret != 0) {
+      _E("mkdir(%s) is failed. errno(%d)", path.c_str(), errno);
+      path = "";
+    }
+  }
+
+  return path;
+}
+
+std::string Path::Get(const std::string& file_name) {
+  return Get() + file_name;
+}
+
+}  // namespace internal
+}  // namespace preference
diff --git a/preference/path-internal.hh b/preference/path-internal.hh
new file mode 100644 (file)
index 0000000..e250a6b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_PATH_INTERNAL_HH_
+#define PREFERENCE_PATH_INTERNAL_HH_
+
+#include <string>
+
+namespace preference {
+namespace internal {
+
+class Path {
+ public:
+  static std::string Get();
+  static std::string Get(const std::string& file_name);
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_PATH_INTERNAL_HH_
diff --git a/preference/preference-internal.cc b/preference/preference-internal.cc
new file mode 100644 (file)
index 0000000..2363331
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021 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 "preference/preference-internal.hh"
+
+namespace preference {
+namespace internal {
+
+Preference::Preference(IEventListener* listener)
+    : backend_(new FileBackend()),
+      listener_(listener) {
+}
+
+int Preference::SetInt(const std::string& key, int value) {
+  Data d(key);
+  d.SetInt(value);
+  return backend_->Set(d);
+}
+
+int Preference::SetDouble(const std::string& key, double value) {
+  Data d(key);
+  d.SetDouble(value);
+  return backend_->Set(d);
+}
+
+int Preference::SetString(const std::string& key, const char* value) {
+  Data d(key);
+  d.SetString(value);
+  return backend_->Set(d);
+}
+
+int Preference::SetBoolean(const std::string& key, bool value) {
+  Data d(key);
+  d.SetBoolean(value);
+  return backend_->Set(d);
+}
+
+int Preference::GetInt(const std::string& key) {
+  auto d = backend_->Get(key);
+  if (d == nullptr)
+    return -1;
+
+  return d->GetInt();
+}
+
+double Preference::GetDouble(const std::string& key) {
+  auto d = backend_->Get(key);
+  if (d == nullptr)
+    return -1;
+
+  return d->GetDouble();
+}
+
+std::string Preference::GetString(const std::string& key) {
+  auto d = backend_->Get(key);
+  if (d == nullptr)
+    return std::string("");
+
+  return d->GetString();
+}
+
+bool Preference::GetBoolean(const std::string& key) {
+  auto d = backend_->Get(key);
+  if (d == nullptr)
+    return false;
+
+  return d->GetBoolean();
+}
+
+int Preference::GetType(const std::string& key) {
+  auto d = backend_->Get(key);
+  if (d == nullptr)
+    return 0;
+
+  return static_cast<int>(d->GetType());
+}
+
+bool Preference::IsExisting(const std::string& key) {
+  return backend_->IsExisting(key);
+}
+
+int Preference::Remove(const std::string& key) {
+  return backend_->Remove(key);
+}
+
+int Preference::RemoveAll() {
+  return backend_->RemoveAll();
+}
+
+std::vector<std::string> Preference::GetKeys() {
+  return backend_->GetKeys();
+}
+
+int Preference::AddWatch(const std::string& key) {
+  return backend_->AddWatch(key, this);
+}
+
+int Preference::RemoveWatch(const std::string& key) {
+  return backend_->RemoveWatch(key);
+}
+
+void Preference::OnDataCreated(const std::string& key) {
+  if (listener_ == nullptr)
+    return;
+
+  listener_->OnCreated(key);
+}
+
+void Preference::OnDataUpdated(const std::string& key) {
+  if (listener_ == nullptr)
+    return;
+
+  listener_->OnUpdated(key);
+}
+
+void Preference::OnDataDeleted(const std::string& key) {
+  if (listener_ == nullptr)
+    return;
+
+  listener_->OnDeleted(key);
+}
+
+}  // namespace internal
+}  // namespace preference
diff --git a/preference/preference-internal.hh b/preference/preference-internal.hh
new file mode 100644 (file)
index 0000000..394373a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021 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 PREFERENCE_PREFERENCE_INTERNAL_HH_
+#define PREFERENCE_PREFERENCE_INTERNAL_HH_
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include "preference/file-backend-internal.hh"
+
+namespace preference {
+namespace internal {
+
+class Preference : private IDataEvent {
+ public:
+  class IEventListener {
+   public:
+    virtual void OnCreated(const std::string& key) = 0;
+    virtual void OnUpdated(const std::string& key) = 0;
+    virtual void OnDeleted(const std::string& key) = 0;
+  };
+
+  Preference(IEventListener* listener);
+  ~Preference() = default;
+
+  int SetInt(const std::string& key, int value);
+  int SetDouble(const std::string& key, double value);
+  int SetString(const std::string& key, const char* value);
+  int SetBoolean(const std::string& key, bool value);
+
+  int GetInt(const std::string& key);
+  double GetDouble(const std::string& key);
+  std::string GetString(const std::string& key);
+  bool GetBoolean(const std::string& key);
+  int GetType(const std::string& key);
+
+  bool IsExisting(const std::string& key);
+  int Remove(const std::string& key);
+  int RemoveAll();
+  std::vector<std::string> GetKeys();
+
+  int AddWatch(const std::string& key);
+  int RemoveWatch(const std::string& key);
+
+ private:
+  void OnDataCreated(const std::string& key) override;
+  void OnDataUpdated(const std::string& key) override;
+  void OnDataDeleted(const std::string& key) override;
+
+ private:
+  std::unique_ptr<IBackend> backend_;
+  IEventListener* listener_ = nullptr;
+};
+
+}  // namespace internal
+}  // namespace preference
+
+#endif  // PREFERENCE_PREFERENCE_INTERNAL_HH_
diff --git a/preference/stub.cc b/preference/stub.cc
new file mode 100644 (file)
index 0000000..39d71b7
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2021 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 <app_common.h>
+#include <app_preference.h>
+
+#include <map>
+#include <mutex>
+#include <thread>
+
+#include "include/app_preference.h"
+#include "preference/log-internal.hh"
+#include "preference/preference-internal.hh"
+
+#undef API
+#define API __attribute__ ((visibility("default")))
+
+namespace {
+
+template<typename T>
+class Event {
+ public:
+  Event(T cb, void* user_data) : cb_(cb), user_data_(user_data) {}
+
+  T cb_;
+  void* user_data_;
+};
+
+class PrefExt : public preference::internal::Preference,
+                public preference::internal::Preference::IEventListener {
+ public:
+  PrefExt() : Preference(this) {
+  }
+
+  int AddWatch(const char* key, preference_changed_cb cb, void* user_data) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    if (Preference::AddWatch(key) < 0)
+      return -1;
+
+    map_[std::string(key)] = std::unique_ptr<Event<preference_changed_cb>>(
+        new Event<preference_changed_cb>(cb, user_data));
+
+    return 0;
+  }
+
+  int RemoveWatch(const char* key) {
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    auto i = map_.find(key);
+    if (i == map_.end())
+      return -1;
+
+    map_.erase(key);
+    Preference::RemoveWatch(std::string(key));
+    return 0;
+  }
+
+ private:
+  std::recursive_mutex& GetMutex() const {
+    return mutex_;
+  }
+
+  void OnCreated(const std::string& key) override {
+    SECURE_LOGD("key(%s)", key.c_str());
+  }
+
+  void OnUpdated(const std::string& key) override {
+    SECURE_LOGD("key(%s)", key.c_str());
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    auto i = map_.find(key);
+    if (i != map_.end()) {
+      auto& ev = i->second;
+      ev->cb_(key.c_str(), ev->user_data_);
+    }
+  }
+
+  void OnDeleted(const std::string& key) override {
+    SECURE_LOGD("key(%s)", key.c_str());
+    std::lock_guard<std::recursive_mutex> lock(GetMutex());
+    auto i = map_.find(key);
+    if (i == map_.end())
+      return;
+
+    map_.erase(key);
+    Preference::RemoveWatch(key);
+  }
+
+ private:
+  std::map<std::string, std::unique_ptr<Event<preference_changed_cb>>> map_;
+  mutable std::recursive_mutex mutex_;
+};
+
+PrefExt pref;
+
+}  // namespace
+
+extern "C" API int preference_set_int(const char* key, int intval) {
+  if (key == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  int ret = pref.SetInt(key, intval);
+  if (ret < 0) {
+    _E("Failed to set integer value");
+    return PREFERENCE_ERROR_IO_ERROR;
+  }
+
+  SECURE_LOGD("key(%s), value(%d)", key, intval);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_set_boolean(const char* key, bool boolval) {
+  if (key == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  int ret = pref.SetBoolean(key, boolval);
+  if (ret < 0) {
+    _E("Failed to set boolean value");
+    return PREFERENCE_ERROR_IO_ERROR;
+  }
+
+  SECURE_LOGD("key(%s), value(%d)", key, boolval);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_set_double(const char* key, double dblval) {
+  if (key == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  int ret = pref.SetDouble(key, dblval);
+  if (ret < 0) {
+    _E("Failed to set double value");
+    return PREFERENCE_ERROR_IO_ERROR;
+  }
+
+  SECURE_LOGD("key(%s), value(%lf)", key, dblval);
+
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_set_string(const char* key, const char* strval) {
+  if (key == nullptr || strval == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  int ret = pref.SetString(key, strval);
+  if (ret < 0) {
+    _E("Failed to set string value");
+    return PREFERENCE_ERROR_IO_ERROR;
+  }
+
+  SECURE_LOGD("key(%s), value(%s)", key, strval);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_get_int(const char* key, int* intval) {
+  if (key == nullptr || intval == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key))
+    return PREFERENCE_ERROR_NO_KEY;
+
+  *intval = pref.GetInt(key);
+  SECURE_LOGD("key(%s), value(%d)", key, *intval);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_get_boolean(const char* key, bool* boolval) {
+  if (key == nullptr || boolval == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key))
+    return PREFERENCE_ERROR_NO_KEY;
+
+  *boolval = pref.GetBoolean(key);
+  SECURE_LOGD("key(%s), value(%d)", key, *boolval);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_get_double(const char* key, double* dblval) {
+  if (key == nullptr || dblval == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key))
+    return PREFERENCE_ERROR_NO_KEY;
+
+  *dblval = pref.GetDouble(key);
+  SECURE_LOGD("key(%s), value(%lf)", key, *dblval);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_get_string(const char* key, char** value) {
+  if (key == nullptr || value == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key))
+    return PREFERENCE_ERROR_NO_KEY;
+
+  *value = strdup(pref.GetString(key).c_str());
+  SECURE_LOGD("key(%s), value(%s)", key, *value);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_remove(const char* key) {
+  if (key == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key)) {
+    _E("%s doesn't exist", key);
+    return PREFERENCE_ERROR_NO_KEY;
+  }
+
+  int ret = pref.Remove(key);
+  if (ret < 0) {
+    _E("Failed to remove key(%s)", key);
+    return PREFERENCE_ERROR_IO_ERROR;
+  }
+
+  SECURE_LOGD("key(%s)", key);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_is_existing(const char* key, bool* exist) {
+  if (key == nullptr || exist == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  *exist = pref.IsExisting(key);
+  SECURE_LOGD("key(%s), existence(%d)", key, *exist);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_remove_all(void) {
+  int ret = pref.RemoveAll();
+  if (ret < 0) {
+    _E("Failed to delete all keys");
+    return PREFERENCE_ERROR_IO_ERROR;
+  }
+
+  SECURE_LOGD("RemoveAll");
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_set_changed_cb(const char* key,
+    preference_changed_cb callback, void* user_data) {
+  if (key == nullptr || callback == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key)) {
+    _E("Failed to find key(%s)", key);
+    return PREFERENCE_ERROR_NO_KEY;
+  }
+
+  int ret = pref.AddWatch(key, callback, user_data);
+  if (ret < 0) {
+    _E("Failed to add watch");
+    return PREFERENCE_ERROR_OUT_OF_MEMORY;
+  }
+
+  SECURE_LOGD("key(%s)", key);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_unset_changed_cb(const char* key) {
+  if (key == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key)) {
+    _E("Failed to find key(%s)", key);
+    return PREFERENCE_ERROR_NO_KEY;
+  }
+
+  int ret = pref.RemoveWatch(key);
+  if (ret < 0) {
+    _E("Failed to remove watch");
+    return PREFERENCE_ERROR_NO_KEY;
+  }
+
+  SECURE_LOGD("key(%s)", key);
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_foreach_item(preference_item_cb callback,
+    void* user_data) {
+  if (callback == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  auto keys = pref.GetKeys();
+  for (auto& i : keys) {
+    if (!callback(i.c_str(), user_data))
+      break;
+  }
+
+  return PREFERENCE_ERROR_NONE;
+}
+
+extern "C" API int preference_get_type(const char* key,
+    preference_type_e* type) {
+  if (key == nullptr || type == nullptr) {
+    _E("Invalid parameter");
+    return PREFERENCE_ERROR_INVALID_PARAMETER;
+  }
+
+  if (!pref.IsExisting(key)) {
+    *type = PREFERENCE_TYPE_NONE;
+    return PREFERENCE_ERROR_NONE;
+  }
+
+  *type = static_cast<preference_type_e>(pref.GetType(key));
+  SECURE_LOGD("key(%s), type(%d)", key, *type);
+  return PREFERENCE_ERROR_NONE;
+}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
deleted file mode 100644 (file)
index b3a18e8..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(fw_name "capi-appfw-preference")
-
-PROJECT(${fw_name})
-
-SET(CMAKE_INSTALL_PREFIX /usr)
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-
-SET(INC_DIR ${CMAKE_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${INC_DIR})
-
-SET(requires "dlog capi-base-common sqlite3 glib-2.0 capi-appfw-app-common")
-SET(pc_requires "capi-base-common")
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_name} REQUIRED ${requires})
-FOREACH(flag ${${fw_name}_CFLAGS})
-    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-
-IF("${ARCH}" STREQUAL "arm")
-    ADD_DEFINITIONS("-DTARGET")
-ENDIF("${ARCH}" STREQUAL "arm")
-
-ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
-ADD_DEFINITIONS("-DSLP_DEBUG")
-
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
-
-add_library(${fw_name} SHARED
-               preference.c
-               preference_inoti.c
-               )
-
-TARGET_LINK_LIBRARIES(${fw_name} capi-appfw-app-common ${${fw_name}_LDFLAGS})
-
-SET_TARGET_PROPERTIES(${fw_name}
-     PROPERTIES
-     VERSION ${FULLVER}
-     SOVERSION ${MAJORVER}
-     CLEAN_DIRECT_OUTPUT 1
-)
-
-INSTALL(TARGETS ${fw_name} DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(
-        DIRECTORY ${INC_DIR}/ DESTINATION include/appfw
-        FILES_MATCHING
-        PATTERN "*_private.h" EXCLUDE
-        PATTERN "${INC_DIR}/*.h"
-        )
-
-SET(PC_NAME ${fw_name})
-SET(PC_REQUIRED ${pc_requires})
-SET(PC_LDFLAGS -l${fw_name})
-
-CONFIGURE_FILE(
-    ${CMAKE_SOURCE_DIR}/${fw_name}.pc.in
-    ${CMAKE_SOURCE_DIR}/${fw_name}.pc
-    @ONLY
-)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-
-ADD_SUBDIRECTORY(tool)
diff --git a/src/preference.c b/src/preference.c
deleted file mode 100644 (file)
index 4547d5f..0000000
+++ /dev/null
@@ -1,1638 +0,0 @@
-/*
- * Copyright (c) 2011 - 2016 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 <stdlib.h>
-#include <limits.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/xattr.h>
-#include <ctype.h>
-#include <string.h>
-#include <execinfo.h>
-#include <glib.h>
-
-#include <app_preference.h>
-#include <app_preference_internal.h>
-#include <app_common.h>
-
-#include <sys/syscall.h>
-
-#ifdef PREFERENCE_TIMECHECK
-#include <sys/time.h>
-#endif
-
-#ifndef API
-#define API __attribute__ ((visibility("default")))
-#endif
-
-#define PREFERENCE_ERROR_RETRY_CNT 7
-#define PREFERENCE_ERROR_RETRY_SLEEP_UTIME 10000
-
-#define DELIMITER 29
-
-static int g_posix_errno;
-static int g_preference_errno;
-static char *g_pref_dir_path = NULL;
-
-enum preference_op_t {
-       PREFERENCE_OP_GET = 0,
-       PREFERENCE_OP_SET = 1
-};
-
-#ifdef PREFERENCE_TIMECHECK
-double correction, startT;
-
-double set_start_time(void)
-{
-       struct timeval tv;
-       double curtime;
-
-       gettimeofday(&tv, NULL);
-       curtime = tv.tv_sec * 1000 + (double)tv.tv_usec / 1000;
-       return curtime;
-}
-
-double exec_time(double start)
-{
-       double end = set_start_time();
-       return (end - start - correction);
-}
-
-int init_time(void)
-{
-       double temp_t;
-       temp_t = set_start_time();
-       correction = exec_time(temp_t);
-
-       return 0;
-}
-#endif
-
-char *_preference_get_pref_dir_path()
-{
-       char *app_data_path = NULL;
-
-       if (!g_pref_dir_path) {
-               g_pref_dir_path = (char *)malloc(PREFERENCE_KEY_PATH_LEN + 1);
-               if (!g_pref_dir_path) {
-                       ERR("Out of memory");
-                       return NULL;
-               }
-
-               if ((app_data_path = app_get_data_path()) == NULL) {
-                       /* LCOV_EXCL_START */
-                       ERR("IO_ERROR(0x%08x) : fail to get data directory", PREFERENCE_ERROR_IO_ERROR);
-                       free(g_pref_dir_path);
-                       g_pref_dir_path = NULL;
-                       return NULL;
-                       /* LCOV_EXCL_STOP */
-               }
-
-               snprintf(g_pref_dir_path, PREFERENCE_KEY_PATH_LEN, "%s%s", app_data_path, PREF_DIR);
-               INFO("pref_dir_path: %s", g_pref_dir_path);
-               free(app_data_path);
-       }
-       return g_pref_dir_path;
-}
-
-int _preference_keynode_set_keyname(keynode_t *keynode, const char *keyname)
-{
-       if (keynode->keyname) free(keynode->keyname);
-       keynode->keyname = strndup(keyname, PREFERENCE_KEY_PATH_LEN);
-       retvm_if(keynode->keyname == NULL, PREFERENCE_ERROR_IO_ERROR, "strndup Fails");
-       return PREFERENCE_ERROR_NONE;
-}
-
-static inline void _preference_keynode_set_value_int(keynode_t *keynode, const int value)
-{
-       keynode->type = PREFERENCE_TYPE_INT;
-       keynode->value.i = value;
-}
-
-static inline void _preference_keynode_set_value_boolean(keynode_t *keynode, const int value)
-{
-       keynode->type = PREFERENCE_TYPE_BOOLEAN;
-       keynode->value.b = !!value;
-}
-
-static inline void _preference_keynode_set_value_double(keynode_t *keynode, const double value)
-{
-       keynode->type = PREFERENCE_TYPE_DOUBLE;
-       keynode->value.d = value;
-}
-
-static inline void _preference_keynode_set_value_string(keynode_t *keynode, const char *value)
-{
-       keynode->type = PREFERENCE_TYPE_STRING;
-       keynode->value.s = strdup(value);
-}
-
-__attribute__ ((gnu_inline)) inline keynode_t *_preference_keynode_new(void)
-{
-       keynode_t *keynode;
-       keynode = calloc(1, sizeof(keynode_t));
-
-       return keynode;
-}
-
-__attribute__ ((gnu_inline)) inline void _preference_keynode_free(keynode_t *keynode)
-{
-       if (keynode) {
-               if (keynode->keyname)
-                       free(keynode->keyname);
-               if (keynode->type == PREFERENCE_TYPE_STRING && keynode->value.s)
-                       free(keynode->value.s);
-               free(keynode);
-       }
-}
-
-int _preference_get_key_name(const char *path, char **keyname)
-{
-       int read_size = 0;
-       size_t keyname_len = 0;
-       char *convert_key = NULL;
-       FILE *fp = NULL;
-
-       if ((fp = fopen(path, "r")) == NULL)
-               return PREFERENCE_ERROR_FILE_OPEN;
-
-       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
-       if (read_size <= 0 || keyname_len > PREFERENCE_KEY_PATH_LEN) {
-               fclose(fp);
-               return PREFERENCE_ERROR_FILE_FREAD;
-       }
-
-       convert_key = (char *)calloc(1, keyname_len+1);
-       if (convert_key == NULL) {
-               LOGE("memory alloc failed");
-               fclose(fp);
-               return PREFERENCE_ERROR_OUT_OF_MEMORY;
-       }
-
-       read_size = fread((void *)convert_key, keyname_len, 1, fp);
-       if (read_size <= 0) {
-               free(convert_key);
-               fclose(fp);
-               return PREFERENCE_ERROR_FILE_FREAD;
-       }
-
-       *keyname = convert_key;
-
-       fclose(fp);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-int _preference_get_key_path(keynode_t *keynode, char *path)
-{
-       const char *key = NULL;
-       char *pref_dir_path = NULL;
-       gchar *convert_key;
-       char *keyname = keynode->keyname;
-
-       if (!keyname) {
-               LOGE("keyname is null");
-               return PREFERENCE_ERROR_WRONG_PREFIX;
-       }
-
-       pref_dir_path = _preference_get_pref_dir_path();
-       if (!pref_dir_path) {
-               LOGE("_preference_get_pref_dir_path() failed.");
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
-                                                       keyname,
-                                                       strlen(keyname));
-       if (convert_key == NULL) {
-               LOGE("fail to convert");
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       key = (const char *)convert_key;
-
-       snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, key);
-
-       g_free(convert_key);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static int _preference_set_key_check_pref_dir()
-{
-       char *pref_dir_path = NULL;
-       mode_t dir_mode = 0664 | 0111;
-       char err_buf[ERR_LEN] = {0,};
-
-       pref_dir_path = _preference_get_pref_dir_path();
-       if (!pref_dir_path) {
-               LOGE("_preference_get_pref_dir_path() failed.");
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       if (access(pref_dir_path, F_OK) < 0) {
-               if (mkdir(pref_dir_path, dir_mode) < 0) {
-                       strerror_r(errno, err_buf, sizeof(err_buf));
-                       ERR("mkdir() failed(%d/%s)", errno, err_buf);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static int _preference_set_key_creation(const char *path)
-{
-       int fd;
-       mode_t temp;
-       char err_buf[ERR_LEN] = {0,};
-
-       temp = umask(0000);
-       fd = open(path, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
-       umask(temp);
-
-       if (fd == -1) {
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("open(rdwr,create) error: %d(%s)", errno, err_buf);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-       close(fd);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static int _preference_set_file_lock(int fd, short type)
-{
-       struct flock l;
-
-       l.l_type = type;
-       l.l_start = 0;          /*Start at begin*/
-       l.l_whence = SEEK_SET;
-       l.l_len = 0;            /*Do it with whole file*/
-
-       return fcntl(fd, F_SETLK, &l);
-}
-
-/* LCOV_EXCL_START */
-static int _preference_get_pid_of_file_lock_owner(int fd, short type)
-{
-       struct flock l;
-
-       l.l_type = type;
-       l.l_start = 0;          /*Start at begin*/
-       l.l_whence = SEEK_SET;
-       l.l_len = 0;            /*Do it with whole file*/
-
-       if (fcntl(fd, F_GETLK, &l) < 0) {
-               WARN("error in getting lock info");
-               return -1;
-       }
-
-       if (l.l_type == F_UNLCK)
-               return 0;
-       else
-               return l.l_pid;
-}
-/* LCOV_EXCL_STOP */
-
-static int _preference_set_read_lock(int fd)
-{
-       return _preference_set_file_lock(fd, F_RDLCK);
-}
-
-static int _preference_set_write_lock(int fd)
-{
-       return _preference_set_file_lock(fd, F_WRLCK);
-}
-
-static int _preference_set_unlock(int fd)
-{
-       return _preference_set_file_lock(fd, F_UNLCK);
-}
-
-/* LCOV_EXCL_START */
-static void _preference_log_subject_label(void)
-{
-       int fd;
-       int ret;
-       char smack_label[256] = {0,};
-       char curren_path[256] = {0,};
-       int tid;
-       char err_buf[ERR_LEN] = {0,};
-
-       tid = (int)syscall(SYS_gettid);
-       snprintf(curren_path, sizeof(curren_path)-1, "/proc/%d/attr/current", tid);
-       fd = open(curren_path, O_RDONLY);
-       if (fd < 0) {
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               LOGE("fail to open self current attr (err: %s)", err_buf);
-               return;
-       }
-
-       ret = read(fd, smack_label, sizeof(smack_label)-1);
-       if (ret < 0) {
-               close(fd);
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               LOGE("fail to open self current attr (err: %s)", err_buf);
-               return;
-       }
-
-       ERR("current(%d) subject label : %s", tid, smack_label);
-
-       close(fd);
-}
-/* LCOV_EXCL_STOP */
-
-static int _preference_check_retry_err(keynode_t *keynode, int preference_errno, int io_errno, int op_type)
-{
-       int is_busy_err = 0;
-       int rc = 0;
-       char path[PATH_MAX] = {0,};
-       char err_buf[ERR_LEN] = {0,};
-
-       if (preference_errno == PREFERENCE_ERROR_FILE_OPEN) {
-               switch (io_errno) {
-               case ENOENT:
-                       if (op_type == PREFERENCE_OP_SET) {
-                               rc = _preference_get_key_path(keynode, path);
-                               if (rc != PREFERENCE_ERROR_NONE) {
-                                       /* LCOV_EXCL_START */
-                                       ERR("_preference_get_key_path error");
-                                       _preference_log_subject_label();
-                                       break;
-                                       /* LCOV_EXCL_STOP */
-                               }
-
-                               rc = _preference_set_key_check_pref_dir();
-                               if (rc != PREFERENCE_ERROR_NONE) {
-                                       /* LCOV_EXCL_START */
-                                       ERR("_preference_set_key_check_pref_dir() failed.");
-                                       _preference_log_subject_label();
-                                       break;
-                                       /* LCOV_EXCL_STOP */
-                               }
-
-                               rc = _preference_set_key_creation(path);
-                               if (rc != PREFERENCE_ERROR_NONE) {
-                                       /* LCOV_EXCL_START */
-                                       ERR("_preference_set_key_creation error : %s", path);
-                                       _preference_log_subject_label();
-                                       break;
-                                       /* LCOV_EXCL_STOP */
-                               }
-                               INFO("%s key is created", keynode->keyname);
-
-                               is_busy_err = 1;
-                       }
-                       break;
-               case EACCES:
-                       _preference_log_subject_label();
-                       break;
-               case EAGAIN:
-               case EMFILE:
-               case ENFILE:
-               case ETXTBSY:
-                       is_busy_err = 1;
-               }
-       } else if (preference_errno == PREFERENCE_ERROR_FILE_CHMOD) {
-               switch (io_errno) {
-               case EINTR:
-               case EBADF:
-                       is_busy_err = 1;
-               }
-       } else if (preference_errno == PREFERENCE_ERROR_FILE_LOCK) {
-               switch (io_errno) {
-               case EBADF:
-               case EAGAIN:
-               case ENOLCK:
-                       is_busy_err = 1;
-               }
-       } else if (preference_errno == PREFERENCE_ERROR_FILE_WRITE) {
-               switch (io_errno) {
-               case 0:
-               case EAGAIN:
-               case EINTR:
-               case EIO:
-               case ENOMEM:
-                       is_busy_err = 1;
-               }
-       } else if (preference_errno == PREFERENCE_ERROR_FILE_FREAD) {
-               switch (io_errno) {
-               case EAGAIN:
-               case EINTR:
-               case EIO:
-                       is_busy_err = 1;
-               }
-       } else {
-               is_busy_err = 0;
-       }
-
-       if (is_busy_err == 1) {
-               return 1;
-       } else {
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("key(%s), check retry err: %d/(%d/%s).", keynode->keyname, preference_errno, io_errno, err_buf);
-               return 0;
-       }
-}
-
-static int _preference_set_key_filesys(keynode_t *keynode, int *io_errno)
-{
-       char path[PATH_MAX] = {0,};
-       FILE *fp = NULL;
-       int ret = -1;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       int err_no = 0;
-       char err_buf[100] = { 0, };
-       int is_write_error = 0;
-       int retry_cnt = 0;
-       size_t keyname_len = 0;
-
-retry_open:
-       errno = 0;
-       err_no = 0;
-       func_ret = PREFERENCE_ERROR_NONE;
-
-       ret = _preference_get_key_path(keynode, path);
-       retv_if(ret != PREFERENCE_ERROR_NONE, ret);
-
-       if ((fp = fopen(path, "w+")) == NULL) {
-               func_ret = PREFERENCE_ERROR_FILE_OPEN;
-               err_no = errno;
-               goto out_return;
-       }
-
-retry:
-       errno = 0;
-       err_no = 0;
-       func_ret = PREFERENCE_ERROR_NONE;
-
-       ret = _preference_set_write_lock(fileno(fp));
-       if (ret == -1) {
-               /* LCOV_EXCL_START */
-               func_ret = PREFERENCE_ERROR_FILE_LOCK;
-               err_no = errno;
-               ERR("file(%s) lock owner(%d)",
-                       keynode->keyname,
-                       _preference_get_pid_of_file_lock_owner(fileno(fp), F_WRLCK));
-               goto out_return;
-               /* LCOV_EXCL_STOP */
-       }
-
-       /* write keyname and size */
-       keyname_len = strlen(keynode->keyname);
-
-       ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp);
-       if (ret <= 0) {
-               /* LCOV_EXCL_START */
-               if (!errno) {
-                       LOGW("number of written items is 0. try again");
-                       errno = EAGAIN;
-               }
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_WRITE;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       ret = fwrite((void *)keynode->keyname, keyname_len, 1, fp);
-       if (ret <= 0) {
-               /* LCOV_EXCL_START */
-               if (!errno) {
-                       LOGW("number of written items is 0. try again");
-                       errno = EAGAIN;
-               }
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_WRITE;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       /* write key type */
-       ret = fwrite((void *)&(keynode->type), sizeof(int), 1, fp);
-       if (ret <= 0) {
-               /* LCOV_EXCL_START */
-               if (!errno) {
-                       LOGW("number of written items is 0. try again");
-                       errno = EAGAIN;
-               }
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_WRITE;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       /* write key value */
-       switch (keynode->type) {
-       case PREFERENCE_TYPE_INT:
-               ret = fwrite((void *)&(keynode->value.i), sizeof(int), 1, fp);
-               if (ret <= 0) is_write_error = 1;
-               break;
-       case PREFERENCE_TYPE_DOUBLE:
-               ret = fwrite((void *)&(keynode->value.d), sizeof(double), 1, fp);
-               if (ret <= 0) is_write_error = 1;
-               break;
-       case PREFERENCE_TYPE_BOOLEAN:
-               ret = fwrite((void *)&(keynode->value.b), sizeof(int), 1, fp);
-               if (ret <= 0) is_write_error = 1;
-               break;
-       case PREFERENCE_TYPE_STRING:
-               ret = fprintf(fp, "%s", keynode->value.s);
-               if (ret < strlen(keynode->value.s))
-                       is_write_error = 1;
-               break;
-       default:
-               func_ret = PREFERENCE_ERROR_WRONG_TYPE;
-               goto out_unlock;
-       }
-
-       if (is_write_error) {
-               /* LCOV_EXCL_START */
-               if (!errno) {
-                       LOGW("number of written items is 0. try again");
-                       errno = EAGAIN;
-               }
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_WRITE;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       fflush(fp);
-
-out_unlock:
-       ret = _preference_set_unlock(fileno(fp));
-       if (ret == -1) {
-               func_ret = PREFERENCE_ERROR_FILE_LOCK;
-               err_no = errno;
-               goto out_return;
-       }
-
-out_return:
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               strerror_r(err_no, err_buf, 100);
-               if (_preference_check_retry_err(keynode, func_ret, err_no, PREFERENCE_OP_SET)) {
-                       if (retry_cnt < PREFERENCE_ERROR_RETRY_CNT) {
-                               WARN("_preference_set_key_filesys(%d-%s) step(%d) failed(%d / %s) retry(%d)", keynode->type, keynode->keyname, func_ret, err_no, err_buf, retry_cnt);
-                               retry_cnt++;
-                               usleep((retry_cnt)*PREFERENCE_ERROR_RETRY_SLEEP_UTIME);
-
-                               if (fp)
-                                       goto retry;
-                               else
-                                       goto retry_open;
-                       } else {
-                               ERR("_preference_set_key_filesys(%d-%s) step(%d) faild(%d / %s) over the retry count.",
-                                       keynode->type, keynode->keyname, func_ret, err_no, err_buf);
-                       }
-               } else {
-                       ERR("_preference_set_key_filesys(%d-%s) step(%d) failed(%d / %s)\n", keynode->type, keynode->keyname, func_ret, err_no, err_buf);
-               }
-       } else if (retry_cnt > 0) {
-               DBG("_preference_set_key_filesys ok with retry cnt(%d)", retry_cnt);
-       }
-
-       if (fp) {
-               if (func_ret == PREFERENCE_ERROR_NONE) {
-                       ret = fdatasync(fileno(fp));
-                       if (ret == -1) {
-                               err_no = errno;
-                               func_ret = PREFERENCE_ERROR_FILE_SYNC;
-                       }
-               }
-               fclose(fp);
-       }
-       *io_errno = err_no;
-
-       return func_ret;
-}
-
-static int _preference_set_key(keynode_t *keynode)
-{
-       int ret = 0;
-       int io_errno = 0;
-       char err_buf[100] = { 0, };
-
-       ret = _preference_set_key_filesys(keynode, &io_errno);
-       if (ret == PREFERENCE_ERROR_NONE) {
-               g_posix_errno = PREFERENCE_ERROR_NONE;
-               g_preference_errno = PREFERENCE_ERROR_NONE;
-       } else {
-               /* LCOV_EXCL_START */
-               strerror_r(io_errno, err_buf, 100);
-               ERR("_preference_set_key(%s) step(%d) failed(%d / %s)", keynode->keyname, ret, io_errno, err_buf);
-               g_posix_errno = io_errno;
-               g_preference_errno = ret;
-               /* LCOV_EXCL_STOP */
-       }
-
-       return ret;
-}
-
-
-/*
- * This function set the integer value of given key
- * @param[in]  key     key
- * @param[in]  intval integer value to set
- * @return 0 on success, -1 on error
- */
-API int preference_set_int(const char *key, int intval)
-{
-       int func_ret = PREFERENCE_ERROR_NONE;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               /* LCOV_EXCL_START */
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-       _preference_keynode_set_value_int(pKeyNode, intval);
-
-       if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) {
-               ERR("preference_set_int(%d) : key(%s/%d) error", getpid(), key, intval);
-               func_ret = PREFERENCE_ERROR_IO_ERROR;
-       } else {
-               INFO("%s(%d) success", key, intval);
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
-* This function set the boolean value of given key
-* @param[in]   key     key
-* @param[in]   boolval boolean value to set
-               (Integer value 1 is 'True', and 0 is 'False')
-* @return 0 on success, -1 on error
-*/
-API int preference_set_boolean(const char *key, bool boolval)
-{
-       int func_ret = PREFERENCE_ERROR_NONE;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               /* LCOV_EXCL_START */
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-       _preference_keynode_set_value_boolean(pKeyNode, boolval);
-
-       if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) {
-               ERR("preference_set_boolean(%d) : key(%s/%d) error", getpid(), key, boolval);
-               func_ret = PREFERENCE_ERROR_IO_ERROR;
-       } else {
-               INFO("%s(%d) success", key, boolval);
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
- * This function set the double value of given key
- * @param[in]  key     key
- * @param[in]  dblval double value to set
- * @return 0 on success, -1 on error
- */
-API int preference_set_double(const char *key, double dblval)
-{
-       int func_ret = PREFERENCE_ERROR_NONE;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               /* LCOV_EXCL_START */
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-       _preference_keynode_set_value_double(pKeyNode, dblval);
-
-       if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) {
-               ERR("preference_set_double(%d) : key(%s/%f) error", getpid(), key, dblval);
-               func_ret = PREFERENCE_ERROR_IO_ERROR;
-       } else {
-               INFO("%s(%f) success", key, dblval);
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
- * This function set the string value of given key
- * @param[in]  key     key
- * @param[in]  strval string value to set
- * @return 0 on success, -1 on error
- */
-API int preference_set_string(const char *key, const char *strval)
-{
-       int func_ret = PREFERENCE_ERROR_NONE;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is NULL");
-       retvm_if(strval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: value is NULL");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               /* LCOV_EXCL_START */
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-       _preference_keynode_set_value_string(pKeyNode, strval);
-
-       if (_preference_set_key(pKeyNode) != PREFERENCE_ERROR_NONE) {
-               ERR("preference_set_string(%d) : key(%s/%s) error", getpid(), key, strval);
-               func_ret = PREFERENCE_ERROR_IO_ERROR;
-       } else {
-               INFO("%s(%s) success", key, strval);
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-static int _preference_get_key_filesys(keynode_t *keynode, int* io_errno)
-{
-       char path[PATH_MAX] = {0,};
-       int ret = -1;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       char err_buf[100] = { 0, };
-       int err_no = 0;
-       int type = 0;
-       FILE *fp = NULL;
-       int retry_cnt = 0;
-       int read_size = 0;
-       size_t keyname_len = 0;
-       int value_int = 0;
-       double value_dbl = 0;
-       char file_buf[BUF_LEN] = {0,};
-       char *value = NULL;
-       char *tmp_value;
-       int value_size = 0;
-       int tmp_value_size = 0;
-
-retry_open:
-       errno = 0;
-       func_ret = PREFERENCE_ERROR_NONE;
-
-       ret = _preference_get_key_path(keynode, path);
-       retv_if(ret != PREFERENCE_ERROR_NONE, ret);
-
-       if ((fp = fopen(path, "r")) == NULL) {
-               func_ret = PREFERENCE_ERROR_FILE_OPEN;
-               err_no = errno;
-               goto out_return;
-       }
-
-retry:
-       err_no = 0;
-       func_ret = PREFERENCE_ERROR_NONE;
-
-       ret = _preference_set_read_lock(fileno(fp));
-       if (ret == -1) {
-               /* LCOV_EXCL_START */
-               func_ret = PREFERENCE_ERROR_FILE_LOCK;
-               err_no = errno;
-               goto out_return;
-               /* LCOV_EXCL_STOP */
-       }
-
-       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
-       if ((read_size <= 0) || (read_size > sizeof(int))) {
-               /* LCOV_EXCL_START */
-               if (!ferror(fp))
-                       errno = ENODATA;
-
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_FREAD;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       ret = fseek(fp, keyname_len, SEEK_CUR);
-       if (ret) {
-               /* LCOV_EXCL_START */
-               if (!ferror(fp))
-                       errno = ENODATA;
-
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_FREAD;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       read_size = fread((void *)&type, sizeof(int), 1, fp);
-       if (read_size <= 0) {
-               /* LCOV_EXCL_START */
-               if (!ferror(fp))
-                       errno = ENODATA;
-
-               err_no = errno;
-               func_ret = PREFERENCE_ERROR_FILE_FREAD;
-               goto out_unlock;
-               /* LCOV_EXCL_STOP */
-       }
-
-       /* read data value */
-       switch (type) {
-       case PREFERENCE_TYPE_INT:
-               read_size = fread((void *)&value_int, sizeof(int), 1, fp);
-               if ((read_size <= 0) || (read_size > sizeof(int))) {
-                       /* LCOV_EXCL_START */
-                       if (!ferror(fp))
-                               LOGW("number of read items for value is wrong. err : %d", errno);
-
-                       err_no = errno;
-                       func_ret = PREFERENCE_ERROR_FILE_FREAD;
-                       goto out_unlock;
-                       /* LCOV_EXCL_STOP */
-               } else {
-                       _preference_keynode_set_value_int(keynode, value_int);
-               }
-
-               break;
-       case PREFERENCE_TYPE_DOUBLE:
-               read_size = fread((void *)&value_dbl, sizeof(double), 1, fp);
-               if ((read_size <= 0) || (read_size > sizeof(double))) {
-                       /* LCOV_EXCL_START */
-                       if (!ferror(fp))
-                               LOGW("number of read items for value is wrong. err : %d", errno);
-
-                       err_no = errno;
-                       func_ret = PREFERENCE_ERROR_FILE_FREAD;
-                       goto out_unlock;
-                       /* LCOV_EXCL_STOP */
-               } else {
-                       _preference_keynode_set_value_double(keynode, value_dbl);
-               }
-
-               break;
-       case PREFERENCE_TYPE_BOOLEAN:
-               read_size = fread((void *)&value_int, sizeof(int), 1, fp);
-               if ((read_size <= 0) || (read_size > sizeof(int))) {
-                       /* LCOV_EXCL_START */
-                       if (!ferror(fp))
-                               LOGW("number of read items for value is wrong. err : %d", errno);
-
-                       err_no = errno;
-                       func_ret = PREFERENCE_ERROR_FILE_FREAD;
-                       goto out_unlock;
-                       /* LCOV_EXCL_STOP */
-               } else {
-                       _preference_keynode_set_value_boolean(keynode, value_int);
-               }
-
-               break;
-       case PREFERENCE_TYPE_STRING:
-               while (fgets(file_buf, sizeof(file_buf), fp)) {
-                       if (value) {
-                               tmp_value_size = value_size + sizeof(file_buf);
-                               tmp_value = (char *) realloc(value, tmp_value_size);
-                               if (tmp_value == NULL) {
-                                       func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY;
-                                       free(value);
-                                       value = NULL;
-                                       break;
-                               }
-
-                               memset(tmp_value + value_size , 0x00, sizeof(file_buf));
-                               strncat(tmp_value, file_buf, tmp_value_size - strlen(tmp_value));
-                               value = tmp_value;
-
-                               value_size = tmp_value_size;
-                               memset(file_buf, 0x00, sizeof(file_buf));
-                       } else {
-                               value_size = sizeof(file_buf) + 1;
-                               value = (char *)malloc(value_size);
-                               if (value == NULL) {
-                                       func_ret = PREFERENCE_ERROR_OUT_OF_MEMORY;
-                                       break;
-                               }
-                               memset(value, 0x00, value_size);
-                               strncpy(value, file_buf, value_size - 1);
-                       }
-               }
-
-               if (ferror(fp)) {
-                       err_no = errno;
-                       func_ret = PREFERENCE_ERROR_FILE_FGETS;
-               } else {
-                       if (value)
-                               _preference_keynode_set_value_string(keynode, value);
-                       else
-                               _preference_keynode_set_value_string(keynode, "");
-               }
-               if (value)
-                       free(value);
-
-               break;
-       default:
-               func_ret = PREFERENCE_ERROR_WRONG_TYPE;
-       }
-
-out_unlock:
-       ret = _preference_set_unlock(fileno(fp));
-       if (ret == -1) {
-               func_ret = PREFERENCE_ERROR_FILE_LOCK;
-               err_no = errno;
-               goto out_return;
-       }
-
-
-out_return:
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               strerror_r(err_no, err_buf, 100);
-
-               if (_preference_check_retry_err(keynode, func_ret, err_no, PREFERENCE_OP_GET)) {
-                       /* LCOV_EXCL_START */
-                       if (retry_cnt < PREFERENCE_ERROR_RETRY_CNT) {
-                               retry_cnt++;
-                               usleep((retry_cnt)*PREFERENCE_ERROR_RETRY_SLEEP_UTIME);
-
-                               if (fp)
-                                       goto retry;
-                               else
-                                       goto retry_open;
-                       } else {
-                               ERR("_preference_get_key_filesys(%s) step(%d) faild(%d / %s) over the retry count.",
-                                       keynode->keyname, func_ret, err_no, err_buf);
-                       }
-                       /* LCOV_EXCL_STOP */
-               }
-       }
-
-       if (fp)
-               fclose(fp);
-
-       *io_errno = err_no;
-
-       return func_ret;
-}
-
-int _preference_get_key(keynode_t *keynode)
-{
-       int ret = 0;
-       int io_errno = 0;
-       char err_buf[100] = {0,};
-
-       ret = _preference_get_key_filesys(keynode, &io_errno);
-       if (ret == PREFERENCE_ERROR_NONE) {
-               g_posix_errno = PREFERENCE_ERROR_NONE;
-               g_preference_errno = PREFERENCE_ERROR_NONE;
-       } else {
-               if (io_errno == ENOENT)
-                       ret = PREFERENCE_ERROR_NO_KEY;
-               else
-                       ret = PREFERENCE_ERROR_IO_ERROR;
-
-               strerror_r(io_errno, err_buf, 100);
-               ERR("_preference_get_key(%s) step(%d) failed(%d / %s)\n", keynode->keyname, ret, io_errno, err_buf);
-               g_posix_errno = io_errno;
-               g_preference_errno = ret;
-       }
-
-       return ret;
-}
-
-
-/*
- * This function get the integer value of given key
- * @param[in]  key     key
- * @param[out] intval output buffer
- * @return 0 on success, -1 on error
- */
-API int preference_get_int(const char *key, int *intval)
-{
-       int func_ret = PREFERENCE_ERROR_IO_ERROR;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-       retvm_if(intval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       func_ret = _preference_get_key(pKeyNode);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("preference_get_int(%d) : key(%s) error", getpid(), key);
-       } else {
-               *intval = pKeyNode->value.i;
-               if (pKeyNode->type == PREFERENCE_TYPE_INT) {
-                       INFO("%s(%d) success", key, *intval);
-                       func_ret = PREFERENCE_ERROR_NONE;
-               } else {
-                       ERR("The type(%d) of keynode(%s) is not INT", pKeyNode->type, pKeyNode->keyname);
-                       func_ret = PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
- * This function get the boolean value of given key
- * @param[in]  key     key
- * @param[out] boolval output buffer
- * @return 0 on success, -1 on error
- */
-API int preference_get_boolean(const char *key, bool *boolval)
-{
-       int func_ret = PREFERENCE_ERROR_IO_ERROR;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-       retvm_if(boolval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       func_ret = _preference_get_key(pKeyNode);
-
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("preference_get_boolean(%d) : %s error", getpid(), key);
-       } else {
-               *boolval = !!(pKeyNode->value.b);
-               if (pKeyNode->type == PREFERENCE_TYPE_BOOLEAN) {
-                       INFO("%s(%d) success", key, *boolval);
-                       func_ret = PREFERENCE_ERROR_NONE;
-               } else {
-                       ERR("The type(%d) of keynode(%s) is not BOOL", pKeyNode->type, pKeyNode->keyname);
-                       func_ret = PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
- * This function get the double value of given key
- * @param[in]  key     key
- * @param[out] dblval output buffer
- * @return 0 on success, -1 on error
- */
-API int preference_get_double(const char *key, double *dblval)
-{
-       int func_ret = PREFERENCE_ERROR_IO_ERROR;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-       retvm_if(dblval == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       func_ret = _preference_get_key(pKeyNode);
-
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("preference_get_double(%d) : %s error", getpid(), key);
-       } else {
-               *dblval = pKeyNode->value.d;
-               if (pKeyNode->type == PREFERENCE_TYPE_DOUBLE) {
-                       INFO("%s(%f) success", key, *dblval);
-                       func_ret = PREFERENCE_ERROR_NONE;
-               } else {
-                       ERR("The type(%d) of keynode(%s) is not DBL", pKeyNode->type, pKeyNode->keyname);
-                       func_ret = PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
- * This function get the string value of given key
- * @param[in]  key     key
- * @param[out] value output buffer
- * @return 0 on success, -1 on error
- */
-API int preference_get_string(const char *key, char **value)
-{
-       int func_ret = PREFERENCE_ERROR_IO_ERROR;
-       keynode_t *pKeyNode;
-       char *tempstr = NULL;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-       retvm_if(value == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: output buffer is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       func_ret = _preference_get_key(pKeyNode);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("preference_get_string(%d) : %s error", getpid(), key);
-       } else {
-               if (pKeyNode->type == PREFERENCE_TYPE_STRING) {
-                       tempstr = pKeyNode->value.s;
-               } else {
-                       ERR("The type(%d) of keynode(%s) is not STR", pKeyNode->type, pKeyNode->keyname);
-                       func_ret = PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-
-               if (tempstr) {
-                       *value = strdup(tempstr);
-                       INFO("%s(%s) success", key, value);
-               }
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-/*
- * This function unset given key
- * @param[in]  key     key
- * @return 0 on success, -1 on error
- */
-API int preference_remove(const char *key)
-{
-       char path[PATH_MAX] = {0,};
-       int ret = -1;
-       int err_retry = PREFERENCE_ERROR_RETRY_CNT;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       char err_buf[ERR_LEN] = {0,};
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-
-       keynode_t *pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = _preference_get_key_path(pKeyNode, path);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("Invalid argument: key is not valid");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       if (access(path, F_OK) == -1) {
-               ERR("Error : key(%s) is not exist", key);
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_NO_KEY;
-       }
-
-       do {
-               ret = remove(path);
-               if (ret == -1) {
-                       strerror_r(errno, err_buf, sizeof(err_buf));
-                       ERR("preference_remove() failed. ret=%d(%s), key(%s)", errno, err_buf, key);
-                       func_ret = PREFERENCE_ERROR_IO_ERROR;
-               } else {
-                       func_ret = PREFERENCE_ERROR_NONE;
-                       break;
-               }
-       } while (err_retry--);
-
-       END_TIME_CHECK;
-
-       _preference_keynode_free(pKeyNode);
-
-       return func_ret;
-}
-
-API int preference_remove_all(void)
-{
-       int ret = -1;
-       int err_retry = PREFERENCE_ERROR_RETRY_CNT;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       DIR *dir;
-       struct dirent *dent = NULL;
-       char *pref_dir_path = NULL;
-       char err_buf[ERR_LEN] = {0,};
-       const char *entry;
-       char *keyname = NULL;
-       char path[PATH_MAX] = {0,};
-
-       START_TIME_CHECK
-
-       pref_dir_path = _preference_get_pref_dir_path();
-       if (!pref_dir_path) {
-               LOGE("_preference_get_pref_dir_path() failed.");
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       dir = opendir(pref_dir_path);
-       if (dir == NULL) {
-               if (errno == ENOENT)
-                       return PREFERENCE_ERROR_NONE;
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               LOGE("opendir() failed. pref_path: %s, error: %d(%s)", pref_dir_path, errno, err_buf);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       keynode_t *pKeyNode = _preference_keynode_new();
-       if (pKeyNode == NULL) {
-               ERR("key malloc fail");
-               closedir(dir);
-               return PREFERENCE_ERROR_OUT_OF_MEMORY;
-       }
-
-       while ((dent = readdir(dir)) != NULL) {
-               entry = dent->d_name;
-               if (entry[0] == '.')
-                       continue;
-
-               snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, entry);
-
-               ret = _preference_get_key_name(path, &keyname);
-               if (ret != PREFERENCE_ERROR_NONE) {
-                       /* LCOV_EXCL_START */
-                       ERR("_preference_get_key_name() failed(%d)", ret);
-                       _preference_keynode_free(pKeyNode);
-                       closedir(dir);
-                       return PREFERENCE_ERROR_IO_ERROR;
-                       /* LCOV_EXCL_STOP */
-               }
-
-               ret = preference_unset_changed_cb(keyname);
-               if (ret != PREFERENCE_ERROR_NONE) {
-                       /* LCOV_EXCL_START */
-                       if (ret == PREFERENCE_ERROR_NO_KEY) {
-                               ERR("can't find %s's cb()", keyname);
-                       } else {
-                               ERR("preference_unset_changed_cb() failed(%d)", ret);
-                               _preference_keynode_free(pKeyNode);
-                               closedir(dir);
-                               free(keyname);
-                               return PREFERENCE_ERROR_IO_ERROR;
-                       }
-                       /* LCOV_EXCL_STOP */
-               }
-
-               do {
-                       ret = remove(path);
-                       if (ret == -1) {
-                               /* LCOV_EXCL_START */
-                               strerror_r(errno, err_buf, sizeof(err_buf));
-                               ERR("preference_remove_all error: %d(%s)", errno, err_buf);
-                               func_ret = PREFERENCE_ERROR_IO_ERROR;
-                               /* LCOV_EXCL_STOP */
-                       } else {
-                               func_ret = PREFERENCE_ERROR_NONE;
-                               break;
-                       }
-               } while (err_retry--);
-
-               free(keyname);
-       }
-
-       _preference_keynode_free(pKeyNode);
-       closedir(dir);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-int preference_is_existing(const char *key, bool *exist)
-{
-       char path[PATH_MAX] = {0,};
-       int ret = -1;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-       retvm_if(exist == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = _preference_get_key_path(pKeyNode, path);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               _preference_keynode_free(pKeyNode);
-               return ret;
-       }
-
-       ret = access(path, F_OK);
-       if (ret == -1) {
-               if (errno != ENOENT) {
-                       ERR("Failed to access key(%s) node. errno(%d)",
-                                       key, errno);
-               }
-               *exist = 0;
-       } else {
-               *exist = 1;
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return func_ret;
-}
-
-API int preference_set_changed_cb(const char *key, preference_changed_cb callback, void *user_data)
-{
-       int func_ret = PREFERENCE_ERROR_IO_ERROR;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-       retvm_if(callback == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: cb(%p)", callback);
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       func_ret = _preference_kdb_add_notify(pKeyNode, callback, user_data);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               if (func_ret == PREFERENCE_ERROR_NO_KEY) {
-                       LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
-                       _preference_keynode_free(pKeyNode);
-                       return PREFERENCE_ERROR_NO_KEY;
-               } else if (errno != 0) {
-                       ERR("preference_notify_key_changed : key(%s) add notify fail", key);
-                       _preference_keynode_free(pKeyNode);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-       INFO("%s noti is added", key);
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-API int preference_unset_changed_cb(const char *key)
-{
-       int func_ret = PREFERENCE_ERROR_IO_ERROR;
-       keynode_t *pKeyNode;
-       char err_buf[ERR_LEN] = {0,};
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: key is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       func_ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       func_ret = _preference_kdb_del_notify(pKeyNode);
-       if (func_ret != PREFERENCE_ERROR_NONE) {
-               if (func_ret == PREFERENCE_ERROR_NO_KEY) {
-                       LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
-                       _preference_keynode_free(pKeyNode);
-                       return PREFERENCE_ERROR_NO_KEY;
-               } else {
-                       if (errno != 0) {
-                               strerror_r(errno, err_buf, sizeof(err_buf));
-                               ERR("preference_unset_changed_cb() failed: key(%s) error(%d:%s)",
-                                               key, errno, err_buf);
-                       } else {
-                               ERR("preference_unset_changed_cb() failed: key(%s)", key);
-                       }
-                       _preference_keynode_free(pKeyNode);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-       INFO("%s noti removed", key);
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-
-API int preference_foreach_item(preference_item_cb callback, void *user_data)
-{
-       int ret = 0;
-       DIR *dir;
-       struct dirent *dent = NULL;
-       char *pref_dir_path = NULL;
-       char err_buf[ERR_LEN] = {0,};
-       const char *entry;
-       char *keyname = NULL;
-       char path[PATH_MAX] = {0,};
-
-
-       START_TIME_CHECK
-       retvm_if(callback == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: cb(%p)", callback);
-
-       pref_dir_path = _preference_get_pref_dir_path();
-       if (!pref_dir_path) {
-               LOGE("_preference_get_pref_dir_path() failed.");
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       dir = opendir(pref_dir_path);
-       if (dir == NULL) {
-               if (errno == ENOENT)
-                       return PREFERENCE_ERROR_NONE;
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               LOGE("opendir() failed. path: %s, error: %d(%s)", pref_dir_path, errno, err_buf);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       while ((dent = readdir(dir)) != NULL) {
-               entry = dent->d_name;
-               if (entry[0] == '.')
-                       continue;
-
-               snprintf(path, PATH_MAX-1, "%s%s", pref_dir_path, entry);
-
-               ret = _preference_get_key_name(path, &keyname);
-               if (ret != PREFERENCE_ERROR_NONE) {
-                       ERR("_preference_get_key_name() failed(%d)", ret);
-                       closedir(dir);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-
-               callback(keyname, user_data);
-               free(keyname);
-       }
-
-       closedir(dir);
-       END_TIME_CHECK
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-/*
- * This function get the type of given key
- * @param[in]  key     key
- * @param[out] type output buffer
- * @return 0 on success, -value on error
- */
-API int preference_get_type(const char *key, preference_type_e *type)
-{
-       int ret;
-       keynode_t *pKeyNode;
-
-       START_TIME_CHECK
-
-       retvm_if(key == NULL, PREFERENCE_ERROR_INVALID_PARAMETER,
-                       "Invalid argument: key is null");
-       retvm_if(type == NULL, PREFERENCE_ERROR_INVALID_PARAMETER,
-                       "Invalid argument: output buffer is null");
-
-       pKeyNode = _preference_keynode_new();
-       retvm_if(pKeyNode == NULL, PREFERENCE_ERROR_OUT_OF_MEMORY, "key malloc fail");
-
-       ret = _preference_keynode_set_keyname(pKeyNode, key);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("set key name error");
-               _preference_keynode_free(pKeyNode);
-               return ret;
-       }
-
-       ret = _preference_get_key(pKeyNode);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("preference_get_int(%d) : key(%s) error", getpid(), key);
-               *type = PREFERENCE_TYPE_NONE;
-       } else {
-               *type = pKeyNode->type;
-       }
-
-       _preference_keynode_free(pKeyNode);
-
-       END_TIME_CHECK
-
-       return ret;
-}
diff --git a/src/preference_db.c b/src/preference_db.c
deleted file mode 100644 (file)
index e87b34a..0000000
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * Copyright (c) 2015 - 2016 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 <unistd.h>
-#include <string.h>
-#include <sqlite3.h>
-
-#include <app_internal.h>
-
-#include <app_preference.h>
-#include <app_preference_internal.h>
-
-#include <dlog.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "CAPI_APPFW_APPLICATION_PREFERENCE"
-#define DBG_MODE (1)
-
-static sqlite3 *pref_db = NULL;
-static bool is_update_hook_registered = false;
-static pref_changed_cb_node_t *head = NULL;
-
-static void _finish(void *data)
-{
-       if (pref_db != NULL) {
-               sqlite3_close(pref_db);
-               pref_db = NULL;
-       }
-}
-
-static int _busy_handler(void *pData, int count)
-{
-       if (5 - count > 0) {
-               LOGD("Busy Handler Called! : PID(%d) / CNT(%d)\n", getpid(), count + 1);
-               usleep((count + 1) * 100000);
-               return 1;
-       } else {
-               LOGD("Busy Handler will be returned SQLITE_BUSY error : PID(%d) \n", getpid());
-               return 0;
-       }
-}
-
-static int _initialize(void)
-{
-       char *data_path = NULL;
-       char db_path[TIZEN_PATH_MAX] = {0, };
-       int ret;
-       char *errmsg;
-
-       if ((data_path = app_get_data_path()) == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to get data directory", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-       snprintf(db_path, sizeof(db_path), "%s/%s", data_path, PREF_DB_NAME);
-       free(data_path);
-
-       ret = sqlite3_open(db_path, &pref_db);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to open db(%s)", PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db));
-               pref_db = NULL;
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_busy_handler(pref_db, _busy_handler, NULL);
-       if (ret != SQLITE_OK)
-               LOGW("IO_ERROR(0x%08x) : fail to register busy handler(%s)\n", PREFERENCE_ERROR_IO_ERROR, sqlite3_errmsg(pref_db));
-
-       ret = sqlite3_exec(pref_db, "CREATE TABLE IF NOT EXISTS pref ( pref_key TEXT PRIMARY KEY, pref_type TEXT, pref_data TEXT)",
-                       NULL, NULL, &errmsg);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to create db table(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
-               sqlite3_free(errmsg);
-               sqlite3_close(pref_db);
-               pref_db = NULL;
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       app_finalizer_add(_finish, NULL);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static int _write_data(const char *key, const char *type, const char *data)
-{
-       int ret;
-       char *buf = NULL;
-       bool exist = false;
-       sqlite3_stmt *stmt;
-
-       if (key == NULL || key[0] == '\0'  || data == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       /* insert data or update data if data already exist */
-       ret = preference_is_existing(key, &exist);
-       if (ret != PREFERENCE_ERROR_NONE)
-               return ret;
-
-       /* to use sqlite3_update_hook, we have to use INSERT/UPDATE operation instead of REPLACE operation */
-       if (exist)
-               buf = sqlite3_mprintf("UPDATE %s SET %s=?, %s=? WHERE %s=?;",
-                                                               PREF_TBL_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_F_KEY_NAME);
-       else
-               buf = sqlite3_mprintf("INSERT INTO %s (%s, %s, %s) values (?, ?, ?);",
-                                                               PREF_TBL_NAME, PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME);
-
-       if (buf == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_prepare(pref_db, buf, strlen(buf), &stmt, NULL);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to prepare query (%d/%s)",
-                       PREFERENCE_ERROR_IO_ERROR,
-                       sqlite3_extended_errcode(pref_db),
-                       sqlite3_errmsg(pref_db));
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       if (exist) {
-               ret = sqlite3_bind_text(stmt, 1, type, strlen(type), SQLITE_STATIC);
-               if (ret != SQLITE_OK) {
-                       LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)",
-                               PREFERENCE_ERROR_IO_ERROR,
-                               sqlite3_extended_errcode(pref_db),
-                               sqlite3_errmsg(pref_db));
-                       sqlite3_finalize(stmt);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-               ret = sqlite3_bind_text(stmt, 2, data, strlen(data), SQLITE_STATIC);
-               if (ret != SQLITE_OK) {
-                       LOGE("IO_ERROR(0x%08x) : fail to bind(2) query (%d/%s)",
-                               PREFERENCE_ERROR_IO_ERROR,
-                               sqlite3_extended_errcode(pref_db),
-                               sqlite3_errmsg(pref_db));
-                       sqlite3_finalize(stmt);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-               ret = sqlite3_bind_text(stmt, 3, key, strlen(key), SQLITE_STATIC);
-               if (ret != SQLITE_OK) {
-                       LOGE("IO_ERROR(0x%08x) : fail to bind(3) query (%d/%s)",
-                               PREFERENCE_ERROR_IO_ERROR,
-                               sqlite3_extended_errcode(pref_db),
-                               sqlite3_errmsg(pref_db));
-                       sqlite3_finalize(stmt);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       } else {
-               ret = sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
-               if (ret != SQLITE_OK) {
-                       LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)",
-                               PREFERENCE_ERROR_IO_ERROR,
-                               sqlite3_extended_errcode(pref_db),
-                               sqlite3_errmsg(pref_db));
-                       sqlite3_finalize(stmt);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-               ret = sqlite3_bind_text(stmt, 2, type, strlen(type), SQLITE_STATIC);
-               if (ret != SQLITE_OK) {
-                       LOGE("IO_ERROR(0x%08x) : fail to bind(2) query (%d/%s)",
-                               PREFERENCE_ERROR_IO_ERROR,
-                               sqlite3_extended_errcode(pref_db),
-                               sqlite3_errmsg(pref_db));
-                       sqlite3_finalize(stmt);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-               ret = sqlite3_bind_text(stmt, 3, data, strlen(data), SQLITE_STATIC);
-               if (ret != SQLITE_OK) {
-                       LOGE("IO_ERROR(0x%08x) : fail to bind(3) query (%d/%s)",
-                               PREFERENCE_ERROR_IO_ERROR,
-                               sqlite3_extended_errcode(pref_db),
-                               sqlite3_errmsg(pref_db));
-                       sqlite3_finalize(stmt);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-
-       ret = sqlite3_step(stmt);
-       if (ret != SQLITE_DONE) {
-               LOGE("IO_ERROR(0x%08x): fail to write data(%d/%s)",
-                       PREFERENCE_ERROR_IO_ERROR,
-                       sqlite3_extended_errcode(pref_db),
-                       sqlite3_errmsg(pref_db));
-               sqlite3_finalize(stmt);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       sqlite3_finalize(stmt);
-       if (buf) {
-               sqlite3_free(buf);
-               buf = NULL;
-       }
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-/* static int _read_data(const char *key, preference_type_e *type, char *data) */
-static int _read_data(const char *key, char *type, char *data)
-{
-       int ret;
-       char *buf;
-       char **result;
-       int rows;
-       int columns;
-       char *errmsg;
-
-       if (key == NULL || key[0] == '\0'  || data == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       if (pref_db == NULL) {
-               if (_initialize() != PREFERENCE_ERROR_NONE) {
-                       LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-
-       buf = sqlite3_mprintf("SELECT %s, %s, %s FROM %s WHERE %s=%Q;",
-                                                       PREF_F_KEY_NAME, PREF_F_TYPE_NAME, PREF_F_DATA_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key);
-       if (buf == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
-       sqlite3_free(buf);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
-               sqlite3_free(errmsg);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       if (rows == 0) {
-               LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
-               sqlite3_free_table(result);
-               return PREFERENCE_ERROR_NO_KEY;
-       }
-
-       snprintf(type, 2, "%s", result[4]);             /* get type value */
-       snprintf(data, BUF_LEN, "%s", result[5]);       /* get data value */
-
-       sqlite3_free_table(result);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-
-int preference_set_int(const char *key, int value)
-{
-       char type[2];
-       char data[BUF_LEN];
-       snprintf(type, 2, "%d", PREFERENCE_TYPE_INT);
-       snprintf(data, BUF_LEN, "%d", value);
-       return _write_data(key, type, data);
-}
-
-int preference_get_int(const char *key, int *value)
-{
-       char type[2];
-       char data[BUF_LEN];
-       int ret;
-
-       if (value == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = _read_data(key, type, data);
-       if (ret == PREFERENCE_ERROR_NONE) {
-               if (atoi(type) == PREFERENCE_TYPE_INT)
-                       *value = atoi(data);
-               else {
-                       LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
-                       return PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       return ret;
-}
-
-int preference_set_double(const char *key, double value)
-{
-       char type[2];
-       char data[BUF_LEN];
-
-       locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL);
-       uselocale(loc);
-
-       snprintf(type, 2, "%d", PREFERENCE_TYPE_DOUBLE);
-       snprintf(data, BUF_LEN, "%f", value);
-
-       freelocale(loc);
-       uselocale(LC_GLOBAL_LOCALE);
-
-       return _write_data(key, type, data);
-}
-
-int preference_get_double(const char *key, double *value)
-{
-       char type[2];
-       char data[BUF_LEN];
-       int ret;
-
-       if (value == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = _read_data(key, type, data);
-       if (ret == PREFERENCE_ERROR_NONE) {
-               if (atoi(type) == PREFERENCE_TYPE_DOUBLE) {
-                       locale_t loc = newlocale(LC_NUMERIC_MASK, "C", NULL);
-                       uselocale(loc);
-
-                       *value = atof(data);
-
-                       freelocale(loc);
-                       uselocale(LC_GLOBAL_LOCALE);
-               } else {
-                       LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
-                       return PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       return ret;
-}
-
-int preference_set_string(const char *key, const char *value)
-{
-       char type[2];
-
-       snprintf(type, 2, "%d", PREFERENCE_TYPE_STRING);
-       if (strlen(value) > (BUF_LEN-1)) {
-               LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-       return _write_data(key, type, value);
-}
-
-int preference_get_string(const char *key, char **value)
-{
-       char type[2];
-       char data[BUF_LEN];
-       int ret;
-
-       if (value == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = _read_data(key, type, data);
-       if (ret == PREFERENCE_ERROR_NONE) {
-               if (atoi(type) == PREFERENCE_TYPE_STRING) {
-                       *value = strdup(data);
-                       if (value == NULL) {
-                               LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
-                               return PREFERENCE_ERROR_OUT_OF_MEMORY;
-                       }
-               } else {
-                       LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
-                       return PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       return ret;
-}
-
-int preference_set_boolean(const char *key, bool value)
-{
-       char type[2];
-       char data[BUF_LEN];
-
-       snprintf(type, 2, "%d", PREFERENCE_TYPE_BOOLEAN);
-       snprintf(data, BUF_LEN, "%d", value);
-
-       return _write_data(key, type, data);
-}
-
-int preference_get_boolean(const char *key, bool *value)
-{
-       char type[2];
-       char data[BUF_LEN];
-       int ret;
-
-       if (value == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = _read_data(key, type, data);
-       if (ret == PREFERENCE_ERROR_NONE) {
-               if (atoi(type) == PREFERENCE_TYPE_BOOLEAN)
-                       *value = (bool)atoi(data);
-               else {
-                       LOGE("INVALID_PARAMETER(0x%08x) : param type(%d)", PREFERENCE_ERROR_INVALID_PARAMETER, atoi(type));
-                       return PREFERENCE_ERROR_INVALID_PARAMETER;
-               }
-       }
-
-       return ret;
-}
-
-/* TODO: below operation is too heavy, let's find the light way to check. */
-int preference_is_existing(const char *key, bool *exist)
-{
-       int ret;
-       char *buf;
-       char **result;
-       int rows;
-       int columns;
-       char *errmsg;
-
-       if (key == NULL || key[0] == '\0' || exist == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       if (pref_db == NULL) {
-               if (_initialize() != PREFERENCE_ERROR_NONE) {
-                       LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-
-       /* check data is exist */
-       buf = sqlite3_mprintf("SELECT %s FROM %s WHERE %s=%Q;", PREF_F_KEY_NAME, PREF_TBL_NAME, PREF_F_KEY_NAME, key);
-       if (buf == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
-       sqlite3_free(buf);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to read data(%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
-               sqlite3_free(errmsg);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       if (rows > 0)
-               *exist = true;
-       else
-               *exist = false;
-
-       sqlite3_free_table(result);
-       return PREFERENCE_ERROR_NONE;
-}
-
-static pref_changed_cb_node_t *_find_node(const char *key)
-{
-       pref_changed_cb_node_t *tmp_node;
-
-       if (key == NULL || key[0] == '\0')
-               return NULL;
-
-       tmp_node = head;
-       while (tmp_node) {
-               if (strcmp(tmp_node->key, key) == 0)
-                       break;
-
-               tmp_node = tmp_node->next;
-       }
-
-       return tmp_node;
-}
-
-static int _add_node(const char *key, preference_changed_cb cb, void *user_data)
-{
-       pref_changed_cb_node_t *tmp_node;
-
-       if (key == NULL || key[0] == '\0' || cb == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       tmp_node = _find_node(key);
-       if (tmp_node != NULL) {
-               tmp_node->cb = cb;
-               tmp_node->user_data = user_data;
-       } else {
-               tmp_node = (pref_changed_cb_node_t *)malloc(sizeof(pref_changed_cb_node_t));
-               if (tmp_node == NULL) {
-                       LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
-                       return PREFERENCE_ERROR_OUT_OF_MEMORY;
-               }
-
-               tmp_node->key = strdup(key);
-               if (tmp_node->key == NULL) {
-                       free(tmp_node);
-                       LOGE("OUT_OF_MEMORY(0x%08x)", PREFERENCE_ERROR_OUT_OF_MEMORY);
-                       return PREFERENCE_ERROR_OUT_OF_MEMORY;
-               }
-
-               if (head != NULL)
-                       head->prev = tmp_node;
-               tmp_node->cb = cb;
-               tmp_node->user_data = user_data;
-               tmp_node->prev = NULL;
-               tmp_node->next = head;
-               head = tmp_node;
-       }
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static int _remove_node(const char *key)
-{
-       pref_changed_cb_node_t *tmp_node;
-
-       if (key == NULL || key[0] == '\0') {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       tmp_node = _find_node(key);
-       if (tmp_node == NULL)
-               return PREFERENCE_ERROR_NONE;
-
-       if (tmp_node->prev != NULL)
-               tmp_node->prev->next = tmp_node->next;
-       else
-               head = tmp_node->next;
-
-       if (tmp_node->next != NULL)
-               tmp_node->next->prev = tmp_node->prev;
-
-       if (tmp_node->key)
-               free(tmp_node->key);
-
-       free(tmp_node);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static void _remove_all_node(void)
-{
-       pref_changed_cb_node_t *tmp_node;
-
-       while (head) {
-               tmp_node = head;
-               head = tmp_node->next;
-
-               if (tmp_node->key)
-                       free(tmp_node->key);
-
-               free(tmp_node);
-       }
-}
-
-static void _update_cb(void *data, int action, char const *db_name, char const *table_name, sqlite_int64 rowid)
-{
-       int ret;
-       char *buf;
-       char **result;
-       int rows;
-       int columns;
-       char *errmsg;
-       pref_changed_cb_node_t *tmp_node;
-
-       /* skip INSERT/DELETE event */
-       if (action != SQLITE_UPDATE)
-               return;
-
-       if (strcmp(table_name, PREF_TBL_NAME) != 0) {
-               SECURE_LOGE("given table name (%s) is not same", table_name);
-               return;
-       }
-
-       buf = sqlite3_mprintf("SELECT %s FROM %s WHERE rowid='%lld';", PREF_F_KEY_NAME, PREF_TBL_NAME, rowid);
-       if (buf == NULL)
-               return;
-
-       ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
-       sqlite3_free(buf);
-       if (ret != SQLITE_OK) {
-               LOGI("fail to read data(%s)", errmsg);
-               sqlite3_free(errmsg);
-               return;
-       }
-
-       if (rows == 0) {
-               sqlite3_free_table(result);
-               return;
-       }
-
-       tmp_node = _find_node(result[1]);
-       if (tmp_node != NULL && tmp_node->cb != NULL)
-               tmp_node->cb(result[1], tmp_node->user_data);
-
-       sqlite3_free_table(result);
-}
-
-int preference_remove(const char *key)
-{
-       int ret;
-       char *buf;
-       bool exist;
-       sqlite3_stmt *stmt;
-
-       ret = preference_is_existing(key, &exist);
-       if (ret != PREFERENCE_ERROR_NONE)
-               return ret;
-
-       if (!exist)
-               return PREFERENCE_ERROR_NO_KEY;
-
-       /* insert data or update data if data already exist */
-       buf = sqlite3_mprintf("DELETE FROM %s WHERE %s = ?",
-                                                       PREF_TBL_NAME, PREF_F_KEY_NAME, key);
-       if (buf == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_prepare(pref_db, buf, strlen(buf), &stmt, NULL);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to prepare query (%d/%s)",
-                       PREFERENCE_ERROR_IO_ERROR,
-                       sqlite3_extended_errcode(pref_db),
-                       sqlite3_errmsg(pref_db));
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to bind(1) query (%d/%s)",
-                       PREFERENCE_ERROR_IO_ERROR,
-                       sqlite3_extended_errcode(pref_db),
-                       sqlite3_errmsg(pref_db));
-               sqlite3_finalize(stmt);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_step(stmt);
-       if (ret != SQLITE_DONE) {
-               LOGE("IO_ERROR(0x%08x): fail to delete data(%d/%s)",
-                       PREFERENCE_ERROR_IO_ERROR,
-                       sqlite3_extended_errcode(pref_db),
-                       sqlite3_errmsg(pref_db));
-               sqlite3_finalize(stmt);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       sqlite3_finalize(stmt);
-       if (buf) {
-               sqlite3_free(buf);
-               buf = NULL;
-       }
-
-       /* if exist, remove changed cb */
-       _remove_node(key);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-int preference_remove_all(void)
-{
-       int ret;
-       char *buf;
-       char *errmsg;
-
-       if (pref_db == NULL) {
-               if (_initialize() != PREFERENCE_ERROR_NONE) {
-                       LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-
-       /* insert data or update data if data already exist */
-       buf = sqlite3_mprintf("DELETE FROM %s;", PREF_TBL_NAME);
-       if (buf == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_exec(pref_db, buf, NULL, NULL, &errmsg);
-       sqlite3_free(buf);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to delete data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
-               sqlite3_free(errmsg);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       /* if exist, remove changed cb */
-       _remove_all_node();
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-int preference_set_changed_cb(const char *key, preference_changed_cb callback, void *user_data)
-{
-       int ret;
-       bool exist;
-
-       ret = preference_is_existing(key, &exist);
-       if (ret != PREFERENCE_ERROR_NONE)
-               return ret;
-
-       if (!exist) {
-               LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
-               return PREFERENCE_ERROR_NO_KEY;
-       }
-
-       if (!is_update_hook_registered) {
-               sqlite3_update_hook(pref_db, _update_cb, NULL);
-               is_update_hook_registered = true;
-       }
-
-       return _add_node(key, callback, user_data);
-}
-
-int preference_unset_changed_cb(const char *key)
-{
-       int ret;
-       bool exist;
-
-       ret = preference_is_existing(key, &exist);
-       if (ret != PREFERENCE_ERROR_NONE)
-               return ret;
-
-       if (!exist) {
-               LOGE("NO_KEY(0x%08x) : fail to find given key(%s)", PREFERENCE_ERROR_NO_KEY, key);
-               return PREFERENCE_ERROR_NO_KEY;
-       }
-
-       return _remove_node(key);
-}
-
-int preference_foreach_item(preference_item_cb callback, void *user_data)
-{
-       int ret;
-       char *buf;
-       char **result;
-       int rows;
-       int columns;
-       char *errmsg;
-       int i;
-
-       if (callback == NULL) {
-               LOGE("INVALID_PARAMETER(0x%08x)", PREFERENCE_ERROR_INVALID_PARAMETER);
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       if (pref_db == NULL) {
-               if (_initialize() != PREFERENCE_ERROR_NONE) {
-                       LOGE("IO_ERROR(0x%08x) : fail to initialize db", PREFERENCE_ERROR_IO_ERROR);
-                       return PREFERENCE_ERROR_IO_ERROR;
-               }
-       }
-
-       buf = sqlite3_mprintf("SELECT %s FROM %s;", PREF_F_KEY_NAME, PREF_TBL_NAME);
-       if (buf == NULL) {
-               LOGE("IO_ERROR(0x%08x) : fail to create query string", PREFERENCE_ERROR_IO_ERROR);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       ret = sqlite3_get_table(pref_db, buf, &result, &rows, &columns, &errmsg);
-       sqlite3_free(buf);
-       if (ret != SQLITE_OK) {
-               LOGE("IO_ERROR(0x%08x) : fail to read data (%s)", PREFERENCE_ERROR_IO_ERROR, errmsg);
-               sqlite3_free(errmsg);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       for (i = 1; i <= rows; i++) {
-               if (callback(result[i], user_data) != true)
-                       break;
-       }
-
-       sqlite3_free_table(result);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
diff --git a/src/preference_inoti.c b/src/preference_inoti.c
deleted file mode 100644 (file)
index 9fc8cfe..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (c) 2015 - 2016 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 <sys/types.h>
-#include <sys/inotify.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <linux/version.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <glib.h>
-
-#include <app_preference.h>
-#include <app_preference_internal.h>
-
-#include <glib.h>
-
-#define INOTY_EVENT_MASK   (IN_CLOSE_WRITE | IN_DELETE_SELF)
-
-/* inotify */
-struct noti_node {
-       int wd;
-       char *keyname;
-       preference_changed_cb cb;
-       void *cb_data;
-       struct noti_node *next;
-};
-typedef struct noti_node noti_node_s;
-static GList *g_notilist;
-
-static int _preference_inoti_comp_with_wd(gconstpointer a, gconstpointer b)
-{
-       int r;
-
-       noti_node_s *key1 = (noti_node_s *) a;
-       noti_node_s *key2 = (noti_node_s *) b;
-
-       r = key1->wd - key2->wd;
-       return r;
-}
-
-static int _kdb_inoti_fd;
-
-static pthread_mutex_t _kdb_inoti_fd_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t _kdb_g_ns_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static GSource *_kdb_handler;
-
-static GList *_preference_copy_noti_list(GList *orig_notilist)
-{
-       GList *copy_notilist = NULL;
-       struct noti_node *n = NULL;
-       struct noti_node *t = NULL;
-       char err_buf[ERR_LEN] = {0,};
-
-       if (!orig_notilist)
-               return NULL;
-
-       orig_notilist = g_list_first(orig_notilist);
-       if (!orig_notilist)
-               return NULL;
-
-       while (orig_notilist) {
-               do {
-                       t = orig_notilist->data;
-                       if (t == NULL) {
-                               WARN("noti item data is null");
-                               break;
-                       }
-
-                       if ((t->keyname == NULL) || (strlen(t->keyname) == 0)) {
-                               WARN("noti item data key name is null");
-                               break;
-                       }
-
-                       n = calloc(1, sizeof(noti_node_s));
-                       if (n == NULL) {
-                               ERR("_preference_copy_noti_list : calloc failed. memory full");
-                               break;
-                       }
-
-                       n->keyname = strndup(t->keyname, PREFERENCE_KEY_PATH_LEN);
-                       if (n->keyname == NULL) {
-                               /* LCOV_EXCL_START */
-                               strerror_r(errno, err_buf, sizeof(err_buf));
-                               ERR("The memory is insufficient, errno: %d (%s)", errno, err_buf);
-                               free(n);
-                               break;
-                               /* LCOV_EXCL_STOP */
-                       }
-                       n->wd = t->wd;
-                       n->cb_data = t->cb_data;
-                       n->cb = t->cb;
-
-                       copy_notilist = g_list_append(copy_notilist, n);
-               } while (0);
-
-               orig_notilist = g_list_next(orig_notilist);
-       }
-       return copy_notilist;
-}
-
-static void _preference_free_noti_node(gpointer data)
-{
-       struct noti_node *n = (struct noti_node *)data;
-       g_free(n->keyname);
-       g_free(n);
-}
-
-static void _preference_free_noti_list(GList *noti_list)
-{
-       g_list_free_full(noti_list, _preference_free_noti_node);
-}
-
-
-static gboolean _preference_kdb_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data)
-{
-       int fd, r, res;
-       struct inotify_event ie;
-       GList *l_notilist = NULL;
-       struct noti_node *t = NULL;
-       GList *noti_list = NULL;
-       keynode_t *keynode;
-
-       fd = g_io_channel_unix_get_fd(src);
-       r = read(fd, &ie, sizeof(ie));
-
-       while (r > 0) {
-               if (ie.mask & INOTY_EVENT_MASK) {
-
-                       INFO("read event from GIOChannel. wd : %d", ie.wd);
-
-                       pthread_mutex_lock(&_kdb_g_ns_mutex);
-                       l_notilist = _preference_copy_noti_list(g_notilist);
-                       pthread_mutex_unlock(&_kdb_g_ns_mutex);
-
-                       if (l_notilist) {
-                               noti_list = g_list_first(l_notilist);
-                               while (noti_list) {
-                                       t = noti_list->data;
-
-                                       keynode = _preference_keynode_new();
-                                       if (keynode == NULL) {
-                                               ERR("key malloc fail");
-                                               break;
-                                       }
-
-                                       if ((t) && (t->wd == ie.wd) && (t->keyname)) {
-                                               res = _preference_keynode_set_keyname(keynode, t->keyname);
-                                               if (res != PREFERENCE_ERROR_NONE) {
-                                                       ERR("_preference_keynode_set_keyname() failed(%d)", res);
-                                                       goto out_func;
-                                               }
-
-                                               if ((ie.mask & IN_DELETE_SELF)) {
-                                                       res = _preference_kdb_del_notify(keynode);
-                                                       if (res != PREFERENCE_ERROR_NONE)
-                                                               ERR("_preference_kdb_del_notify() failed(%d)", res);
-                                               } else {
-                                                       res = _preference_get_key(keynode);
-                                                       if (res != PREFERENCE_ERROR_NONE)
-                                                               ERR("_preference_get_key() failed(%d)", res);
-
-                                                       INFO("key(%s) is changed. cb(%p) called", t->keyname, t->cb);
-                                                       t->cb(t->keyname, t->cb_data);
-                                               }
-                                       } else if ((t) && (t->keyname == NULL)) { /* for debugging */
-                                               ERR("preference keyname is null.");
-                                       }
-out_func:
-                                       _preference_keynode_free(keynode);
-
-                                       noti_list = g_list_next(noti_list);
-                               }
-
-                               _preference_free_noti_list(l_notilist);
-                       }
-               }
-
-               if (ie.len > 0)
-                       (void) lseek(fd, ie.len, SEEK_CUR);
-
-               r = read(fd, &ie, sizeof(ie));
-       }
-       return TRUE;
-}
-
-static int _preference_kdb_noti_init(void)
-{
-       GIOChannel *gio;
-       int ret = 0;
-       char err_buf[ERR_LEN] = { 0, };
-
-       pthread_mutex_lock(&_kdb_inoti_fd_mutex);
-
-       if (0 < _kdb_inoti_fd) {
-               /* LCOV_EXCL_START */
-               ERR("Error: invalid _kdb_inoti_fd");
-               pthread_mutex_unlock(&_kdb_inoti_fd_mutex);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-       _kdb_inoti_fd = inotify_init();
-       if (_kdb_inoti_fd == -1) {
-               /* LCOV_EXCL_START */
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("inotify init: %s", err_buf);
-               pthread_mutex_unlock(&_kdb_inoti_fd_mutex);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-
-       ret = fcntl(_kdb_inoti_fd, F_SETFD, FD_CLOEXEC);
-       if (ret < 0) {
-               /* LCOV_EXCL_START */
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("inotify init: %s", err_buf);
-               pthread_mutex_unlock(&_kdb_inoti_fd_mutex);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-
-       ret = fcntl(_kdb_inoti_fd, F_SETFL, O_NONBLOCK);
-       if (ret < 0) {
-               /* LCOV_EXCL_START */
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("inotify init: %s", err_buf);
-               pthread_mutex_unlock(&_kdb_inoti_fd_mutex);
-               return PREFERENCE_ERROR_IO_ERROR;
-               /* LCOV_EXCL_STOP */
-       }
-
-       pthread_mutex_unlock(&_kdb_inoti_fd_mutex);
-
-       gio = g_io_channel_unix_new(_kdb_inoti_fd);
-       retvm_if(gio == NULL, -1, "Error: create a new GIOChannel");
-
-       g_io_channel_set_flags(gio, G_IO_FLAG_NONBLOCK, NULL);
-
-       _kdb_handler = g_io_create_watch(gio, G_IO_IN);
-       g_source_set_callback(_kdb_handler, (GSourceFunc) _preference_kdb_gio_cb, NULL, NULL);
-       g_source_attach(_kdb_handler, NULL);
-       g_io_channel_unref(gio);
-       g_source_unref(_kdb_handler);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-int _preference_kdb_add_notify(keynode_t *keynode, preference_changed_cb cb, void *data)
-{
-       char path[PATH_MAX];
-       int wd;
-       struct noti_node t, *n, *node;
-       char err_buf[ERR_LEN] = { 0, };
-       int ret = 0;
-       GList *list = NULL;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       char *keyname = keynode->keyname;
-
-       retvm_if((keyname == NULL || cb == NULL), PREFERENCE_ERROR_INVALID_PARAMETER,
-                       "_preference_kdb_add_notify : Invalid argument - keyname(%s) cb(%p)",
-                       keyname, cb);
-
-       if (_kdb_inoti_fd <= 0)
-               if (_preference_kdb_noti_init())
-                       return PREFERENCE_ERROR_IO_ERROR;
-
-       ret = _preference_get_key_path(keynode, path);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("Invalid argument: key is not valid");
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       if (access(path, F_OK) != 0) {
-               if (errno == ENOENT) {
-                       ERR("_preference_kdb_add_notify : Key(%s) does not exist", keyname);
-                       return PREFERENCE_ERROR_NO_KEY;
-               }
-       }
-
-       wd = inotify_add_watch(_kdb_inoti_fd, path, INOTY_EVENT_MASK);
-       if (wd == -1) {
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("_preference_kdb_add_notify : add noti(%s)", err_buf);
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       t.wd = wd;
-
-       pthread_mutex_lock(&_kdb_g_ns_mutex);
-
-       list = g_list_find_custom(g_notilist, &t, (GCompareFunc)_preference_inoti_comp_with_wd);
-       if (list) {
-               /* LCOV_EXCL_START */
-               WARN("_preference_kdb_add_notify : key(%s) change callback(%p)", keyname, cb);
-
-               node = list->data;
-               node->wd = wd;
-               node->cb_data = data;
-               node->cb = cb;
-
-               goto out_func;
-               /* LCOV_EXCL_STOP */
-       }
-
-       n = calloc(1, sizeof(noti_node_s));
-       if (n == NULL) {
-               /* LCOV_EXCL_START */
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("_preference_kdb_add_notify : add noti(%s)", err_buf);
-               func_ret = PREFERENCE_ERROR_IO_ERROR;
-               goto out_func;
-               /* LCOV_EXCL_STOP */
-       }
-
-       n->keyname = strndup(keyname, PREFERENCE_KEY_PATH_LEN);
-       if (n->keyname == NULL) {
-               /* LCOV_EXCL_START */
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("The memory is insufficient, errno: %d (%s)", errno, err_buf);
-               free(n);
-               goto out_func;
-               /* LCOV_EXCL_STOP */
-       }
-       n->wd = wd;
-       n->cb_data = data;
-       n->cb = cb;
-
-       g_notilist = g_list_append(g_notilist, n);
-       if (!g_notilist)
-               ERR("g_list_append fail");
-
-       INFO("cb(%p) is added for %s. tot cb cnt : %d\n", cb, n->keyname, g_list_length(g_notilist));
-
-out_func:
-       pthread_mutex_unlock(&_kdb_g_ns_mutex);
-
-       return func_ret;
-}
-
-int _preference_kdb_del_notify(keynode_t *keynode)
-{
-       int wd = 0;
-       int r = 0;
-       struct noti_node *n = NULL;
-       struct noti_node t;
-       char path[PATH_MAX] = { 0, };
-       char err_buf[ERR_LEN] = { 0, };
-       int del = 0;
-       int ret = 0;
-       char *keyname = keynode->keyname;
-       int func_ret = PREFERENCE_ERROR_NONE;
-       GList *noti_list;
-
-       retvm_if(keyname == NULL, PREFERENCE_ERROR_INVALID_PARAMETER, "Invalid argument: keyname is null");
-
-       ret = _preference_get_key_path(keynode, path);
-       if (ret != PREFERENCE_ERROR_NONE) {
-               ERR("Invalid argument: key is not valid");
-               return PREFERENCE_ERROR_INVALID_PARAMETER;
-       }
-
-       if (access(path, F_OK) != 0) {
-               if (errno == ENOENT) {
-                       ERR("_preference_kdb_del_notify : Key(%s) does not exist", keyname);
-                       return PREFERENCE_ERROR_NO_KEY;
-               }
-       }
-
-       retvm_if(_kdb_inoti_fd == 0, PREFERENCE_ERROR_NONE, "Invalid operation: not exist anything for inotify");
-
-       /* get wd */
-       wd = inotify_add_watch(_kdb_inoti_fd, path, INOTY_EVENT_MASK);
-       if (wd == -1) {
-               if (errno == ENOENT)
-                       func_ret = PREFERENCE_ERROR_NO_KEY;
-               else
-                       func_ret = PREFERENCE_ERROR_IO_ERROR;
-               strerror_r(errno, err_buf, sizeof(err_buf));
-               ERR("Error: inotify_add_watch() [%s]: %s", path, err_buf);
-               return func_ret;
-       }
-
-       pthread_mutex_lock(&_kdb_g_ns_mutex);
-
-       t.wd = wd;
-
-       noti_list = g_list_find_custom(g_notilist, &t, (GCompareFunc)_preference_inoti_comp_with_wd);
-       if (noti_list) {
-               del++;
-
-               n = noti_list->data;
-               g_notilist = g_list_remove(g_notilist, n);
-               g_free(n->keyname);
-               g_free(n);
-
-               r = inotify_rm_watch(_kdb_inoti_fd, wd);
-               if (r == -1) {
-                       strerror_r(errno, err_buf, sizeof(err_buf));
-                       ERR("Error: inotify_rm_watch [%s]: %s", keyname, err_buf);
-                       func_ret = PREFERENCE_ERROR_IO_ERROR;
-               }
-
-               INFO("key(%s) cb is removed. remained noti list total length(%d)",
-                               keyname, g_list_length(g_notilist));
-       }
-
-       if (g_list_length(g_notilist) == 0) {
-               close(_kdb_inoti_fd);
-               _kdb_inoti_fd = 0;
-
-               g_source_destroy(_kdb_handler);
-               _kdb_handler = NULL;
-
-               g_list_free(g_notilist);
-               g_notilist = NULL;
-
-               INFO("all noti list is freed");
-       }
-
-       pthread_mutex_unlock(&_kdb_g_ns_mutex);
-
-       if (del == 0) {
-               errno = ENOENT;
-               func_ret = PREFERENCE_ERROR_NO_KEY;
-       }
-
-       return func_ret;
-}
-
diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt
deleted file mode 100644 (file)
index 144de57..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-SET(tool_name "preference_tool")
-
-SET(CMAKE_INSTALL_PREFIX /usr)
-SET(PREFIX ${CMAKE_INSTALL_PREFIX})
-
-SET(INC_DIR ${CMAKE_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${INC_DIR})
-
-SET(requires "sqlite3 glib-2.0 capi-appfw-app-common libtzplatform-config")
-
-INCLUDE(FindPkgConfig)
-SET(EXTRA_CFLAGS "")
-pkg_check_modules(${tool_name} REQUIRED ${requires})
-FOREACH(flag ${${tool_name}_CFLAGS})
-    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE -Wall -Werror")
-SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
-
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
-
-add_executable(${tool_name}
-               preference_tool.c
-               )
-
-TARGET_LINK_LIBRARIES(${tool_name} ${fw_name} ${${tool_name}_LDFLAGS} -pie)
-INSTALL(TARGETS ${tool_name} DESTINATION bin)
-INSTALL(FILES pref_dump.sh DESTINATION /opt/etc/dump.d/module.d)
-
diff --git a/src/tool/pref_dump.sh b/src/tool/pref_dump.sh
deleted file mode 100644 (file)
index 2b65cb8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-PATH="/usr/bin:/bin:/usr/sbin:/sbin"
-
-PREF_DUMP=$1/pref
-/bin/mkdir -p $PREF_DUMP
-
-for file in `/usr/bin/find /opt/usr/apps/ -name *.pref`
-do
-       chsmack $file >> $PREF_DUMP/pref_value
-       chsmack $file/* >> $PREF_DUMP/pref_value
-       ls -alZ $file >> $PREF_DUMP/pref_value
-       PKG_ID=`echo "$file" | awk -F'/' '{print $5}'`
-       /usr/bin/preference_tool get $PKG_ID >> $PREF_DUMP/pref_value
-       mkdir -p $PREF_DUMP/$PKG_ID
-       cp -rf --preserve=all $file/* $PREF_DUMP/$PKG_ID
-       echo "===============================================" >> $PREF_DUMP/pref_value
-done
diff --git a/src/tool/preference_tool.c b/src/tool/preference_tool.c
deleted file mode 100644 (file)
index 8dfed3b..0000000
+++ /dev/null
@@ -1,1145 +0,0 @@
-/*
- * Copyright (c) 2011 - 2018 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 <errno.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <grp.h>
-#include <linux/limits.h>
-#include <wordexp.h>
-#include <sqlite3.h>
-#include <glib.h>
-#include <locale.h>
-
-#include <app_common_internal.h>
-#include <app_preference.h>
-#include <app_preference_internal.h>
-#include <tzplatform_config.h>
-
-#define PREF_F_KEY_NAME "pref_key"
-#define PREF_F_TYPE_NAME "pref_type"
-#define PREF_F_DATA_NAME "pref_data"
-#define PREF_TBL_NAME "pref"
-
-#define DELIMITER 29
-#define HISTORY "/opt/var/kdb/.restore/.history/preference"
-
-typedef enum {
-       PREFERENCE_OLD_TYPE_INT = 1,
-       PREFERENCE_OLD_TYPE_BOOLEAN,
-       PREFERENCE_OLD_TYPE_DOUBLE,
-       PREFERENCE_OLD_TYPE_STRING
-} old_preference_type_e;
-
-typedef enum {
-       PREFERENCE_OP_RESTORE = 1,
-       PREFERENCE_OP_NEW_CREATE
-} preference_op_type;
-
-static sqlite3 *pref_db;
-
-static void _finish(void *data)
-{
-       if (pref_db != NULL) {
-               sqlite3_close(pref_db);
-               pref_db = NULL;
-       }
-}
-
-static int _busy_handler(void *pData, int count)
-{
-       if (count < 5) {
-               printf("Busy Handler Called!: PID(%d) / CNT(%d)\n",
-                               getpid(), count + 1);
-               usleep((count + 1) * 100000);
-               return 1;
-       }
-
-       return 0;
-}
-
-static int _initialize(const char *db_path)
-{
-       int ret;
-       char *path = strdup(db_path);
-
-       if (!path) {
-               printf("error, strdup(): Insufficient memory available\n");
-               return -1;
-       }
-
-       ret = sqlite3_open(path, &pref_db);
-       if (ret != SQLITE_OK) {
-               printf("error, fail to open db\n");
-               pref_db = NULL;
-               free(path);
-               return -1;
-       }
-
-       ret = sqlite3_busy_handler(pref_db, _busy_handler, NULL);
-       if (ret != SQLITE_OK)
-               printf("error, fail to resigter busy handler\n");
-       app_finalizer_add(_finish, NULL);
-       free(path);
-
-       return 0;
-}
-
-static int __system(const char *cmd)
-{
-       int status;
-       pid_t cpid;
-       wordexp_t p;
-       char **w;
-
-       cpid = fork();
-       if (cpid < 0) {
-               perror("fork");
-               return -1;
-       }
-
-       if (cpid == 0) {
-               /* child */
-               wordexp(cmd, &p, 0);
-               w = p.we_wordv;
-
-               execv(w[0], (char * const *)w);
-
-               wordfree(&p);
-
-               _exit(-1);
-       } else {
-               /* parent */
-               if (waitpid(cpid, &status, 0) == -1) {
-                       perror("waitpid failed\n");
-                       return -1;
-               }
-
-               if (WIFSIGNALED(status)) {
-                       printf("signal(%d)\n", WTERMSIG(status));
-                       perror("exit by signal\n");
-                       return -1;
-               }
-
-               if (!WIFEXITED(status)) {
-                       perror("exit abnormally\n");
-                       return -1;
-               }
-
-               if (WIFEXITED(status) && WEXITSTATUS(status)) {
-                       perror("child return error\n");
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static const char *__get_package_path(const char *package_id)
-{
-       uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-       const char *path;
-
-       tzplatform_set_user(uid);
-       path = tzplatform_mkpath(TZ_USER_APP, package_id);
-       tzplatform_reset_user();
-
-       return path;
-}
-
-static int is_exist_package(const char *pkgid)
-{
-       const char *pkg_path;
-
-       pkg_path = __get_package_path(pkgid);
-       if (pkg_path == NULL) {
-               printf("Failed to get package path(%s)\n", pkgid);
-               return -1;
-       }
-
-       if (access(pkg_path, F_OK) == -1) {
-               printf("package(%s) is not exist.\n", pkgid);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int is_exist_data_dir_in_package(const char *pkgid)
-{
-       char pkg_data_path[PATH_MAX];
-       const char *pkg_path;
-
-       pkg_path = __get_package_path(pkgid);
-       if (pkg_path == NULL) {
-               printf("Failed to get package path(%s)\n", pkgid);
-               return -1;
-       }
-
-       snprintf(pkg_data_path, sizeof(pkg_data_path), "%s/data/", pkg_path);
-       if (access(pkg_data_path, F_OK) == -1) {
-               printf("Data directory is not exist in package(%s).\n", pkgid);
-               return -1;
-       }
-
-       return 0;
-}
-
-static gid_t __get_gid(const char *name)
-{
-       char buf[LINE_MAX];
-       struct group entry;
-       struct group *ge;
-       int ret;
-
-       ret = getgrnam_r(name, &entry, buf, sizeof(buf), &ge);
-       if (ret || ge == NULL) {
-               printf("Fail to get gid of %s\n", name);
-               return -1;
-       }
-
-       return entry.gr_gid;
-}
-
-static int _make_key_path(const char *pkgid, const char *keyname, char **path)
-{
-       const char *key;
-       gchar *convert_key;
-       char pref_dir[PATH_MAX];
-       char *cmd;
-       int size;
-       mode_t dir_mode = 0664 | 0111;
-       const char *pkg_path;
-       uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-       gid_t gid = __get_gid("system_share");
-
-       pkg_path = __get_package_path(pkgid);
-       if (pkg_path == NULL) {
-               printf("Failed to get package path(%s)\n", pkgid);
-               return -1;
-       }
-
-       snprintf(pref_dir, sizeof(pref_dir), "%s/data/.pref", pkg_path);
-       if (access(pref_dir, F_OK) == -1) {
-               if (mkdir(pref_dir, dir_mode) < 0) {
-                       if (is_exist_package(pkgid) < 0)
-                               return -1;
-
-                       if (is_exist_data_dir_in_package(pkgid) < 0)
-                               return -1;
-
-                       printf("pref_dir making failed.(%d/%s)\n",
-                                       errno, strerror(errno));
-                       return -1;
-               }
-               if (chown(pref_dir, uid, gid) < 0) {
-                       printf("chown() failed(%d/%s)\n",
-                                       errno, strerror(errno));
-                       return -1;
-               }
-       }
-
-       size = 1 + snprintf(0, 0, "/usr/bin/chsmack -t -a User::Pkg::\"%s\" %s",
-                       pkgid, pref_dir);
-       cmd = (char *)malloc(size);
-       if (cmd == NULL) {
-               printf("Out of memory\n");
-               return -1;
-       }
-
-       snprintf(cmd, size,
-                       "/usr/bin/chsmack -t -a User::Pkg::\"%s\" %s",
-                       pkgid, pref_dir);
-       if (__system(cmd)) {
-               printf("[pref] cmd error()\n");
-               free(cmd);
-               return -1;
-       }
-       free(cmd);
-
-       convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
-                       keyname, strlen(keyname));
-       if (convert_key == NULL) {
-               LOGE("fail to convert");
-               return PREFERENCE_ERROR_IO_ERROR;
-       }
-
-       key = (const char *)convert_key;
-
-       size = 1 + snprintf(0, 0, "%s/%s", pref_dir, key);
-       *path = (char *)malloc(size);
-       if (*path == NULL) {
-               printf("Out of memory\n");
-               g_free(convert_key);
-               return -1;
-       }
-
-       snprintf(*path, size, "%s/%s", pref_dir, key);
-       g_free(convert_key);
-
-       return 0;
-}
-
-static int _get_key_name(const char *keyfile, char **keyname)
-{
-       int read_size = 0;
-       size_t keyname_len = 0;
-       char *convert_key = NULL;
-       FILE *fp = NULL;
-
-       fp = fopen(keyfile, "r");
-       if (fp == NULL)
-               return PREFERENCE_ERROR_FILE_OPEN;
-
-       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
-       if (read_size <= 0 || keyname_len > PREFERENCE_KEY_PATH_LEN) {
-               fclose(fp);
-               return PREFERENCE_ERROR_FILE_FREAD;
-       }
-
-       convert_key = (char *)calloc(1, keyname_len + 1);
-       if (convert_key == NULL) {
-               LOGE("memory alloc failed");
-               fclose(fp);
-               return PREFERENCE_ERROR_OUT_OF_MEMORY;
-       }
-
-       read_size = fread((void *)convert_key, keyname_len, 1, fp);
-       if (read_size <= 0) {
-               free(convert_key);
-               fclose(fp);
-               return PREFERENCE_ERROR_FILE_FREAD;
-       }
-
-       *keyname = convert_key;
-
-       fclose(fp);
-
-       return PREFERENCE_ERROR_NONE;
-}
-
-static int _create_key(const char *path, const char *pkgid)
-{
-       int fd;
-       char cmd[PATH_MAX];
-       uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
-       gid_t gid = __get_gid("system_share");
-
-       fd = open(path, O_RDWR | O_CREAT,
-                       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
-       if (fd == -1) {
-               printf("[error] %d(%s)\n", errno, strerror(errno));
-               return -1;
-       }
-       close(fd);
-
-       if (chown(path, uid, gid) < 0) {
-               printf("chown() failed(%d/%s)\n", errno, strerror(errno));
-               return -1;
-       }
-
-       snprintf(cmd, sizeof(cmd), "/usr/bin/chsmack -a User::Pkg::\"%s\" %s",
-                       pkgid, path);
-       if (__system(cmd)) {
-               printf("[pref] cmd error()\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-static int _create_new_preference_key(preference_op_type OP, const char *pkgid,
-                       const char *key, const char *type, const char *value)
-{
-       FILE *fp;
-       int ret;
-       char *key_path;
-       size_t keyname_len;
-       int type_i;
-       int temp_i;
-       double temp_d;
-       locale_t loc;
-
-       _make_key_path(pkgid, key, &key_path);
-retry:
-       fp = fopen(key_path, "r+");
-       if (fp == NULL) {
-               if (_create_key(key_path, pkgid) == -1) {
-                       printf("preference key failed to create.(%d/%s)\n",
-                                       errno, strerror(errno));
-                       free(key_path);
-                       return -1;
-               }
-
-               goto retry;
-       }
-
-       /* write keyname and size */
-       keyname_len = strlen(key);
-       ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp);
-       if (ret <= 0) {
-               printf("preference write key name length error(%d/%s)\n",
-                                               errno, strerror(errno));
-               free(key_path);
-               fclose(fp);
-               return -1;
-       }
-
-       ret = fwrite((void *)key, keyname_len, 1, fp);
-       if (ret <= 0) {
-               printf("preference write key name length error(%d/%s)\n",
-                                               errno, strerror(errno));
-               free(key_path);
-               fclose(fp);
-               return -1;
-       }
-
-       loc = newlocale(LC_NUMERIC_MASK, "C", NULL);
-       uselocale(loc);
-
-       if (OP == PREFERENCE_OP_RESTORE) {
-               type_i = atoi(type);
-               switch (type_i) {
-               case PREFERENCE_OLD_TYPE_INT:
-                       type_i = PREFERENCE_TYPE_INT;
-                       break;
-               case PREFERENCE_OLD_TYPE_DOUBLE:
-                       type_i = PREFERENCE_TYPE_DOUBLE;
-                       break;
-               case PREFERENCE_OLD_TYPE_BOOLEAN:
-                       type_i = PREFERENCE_TYPE_BOOLEAN;
-                       break;
-               case PREFERENCE_OLD_TYPE_STRING:
-                       type_i = PREFERENCE_TYPE_STRING;
-                       break;
-               default:
-                       break;
-               }
-       } else { /* OP is PREFERENCE_OP_NEW_CREATE.*/
-               if (strcmp(type, "int") == 0) {
-                       type_i = PREFERENCE_TYPE_INT;
-               } else if (strcmp(type, "double") == 0) {
-                       type_i = PREFERENCE_TYPE_DOUBLE;
-               } else if (strcmp(type, "bool") == 0) {
-                       type_i = PREFERENCE_TYPE_BOOLEAN;
-               } else if (strcmp(type, "string") == 0) {
-                       type_i = PREFERENCE_TYPE_STRING;
-               } else {
-                       printf("key type is invalid.int|double|bool|string\n");
-                       free(key_path);
-                       fclose(fp);
-                       return -1;
-               }
-       }
-
-       ret = fwrite((void *)&type_i, sizeof(int), 1, fp);
-       if (ret <= 0) {
-               if (!errno) {
-                       printf("number of written item is 0. try again\n");
-                       errno = EAGAIN;
-               }
-       }
-
-       switch (type_i) {
-       case PREFERENCE_TYPE_INT:
-               temp_i = atoi(value);
-               ret = fwrite((void *)&temp_i, sizeof(int), 1, fp);
-               if (ret <= 0) {
-                       printf("failed. fwrite() %d\n", ret);
-               } else {
-                       printf("[SET][key]:%s [type]int[value]:%d\n",
-                                       key, temp_i);
-               }
-               break;
-       case PREFERENCE_TYPE_DOUBLE:
-               temp_d = atof(value);
-               ret = fwrite((void *)&temp_d, sizeof(double), 1, fp);
-               if (ret <= 0) {
-                       printf("failed. fwrite() %d\n", ret);
-               } else {
-                       printf("[SET][key]:%s[type]double[value]:%f\n",
-                                       key, temp_d);
-               }
-               break;
-       case PREFERENCE_TYPE_BOOLEAN:
-               temp_i = atoi(value);
-               ret = fwrite((void *)&temp_i, sizeof(int), 1, fp);
-               if (ret <= 0) {
-                       printf("failed. fwrite() %d\n", ret);
-               } else {
-                       printf("[SET][key]:%s [type]bool[value]:%d\n",
-                                       key, temp_i);
-               }
-               break;
-       case PREFERENCE_TYPE_STRING:
-               printf("[SET][key]:%s [type] string [value] %s\n",
-                               key, value);
-               ret = fprintf(fp, "%s", value);
-               if (ftruncate(fileno(fp), ret) == -1) {
-                       printf("[error] ftruncate failed %s(%s)\n",
-                                       key_path, value);
-               }
-               break;
-       default:
-               break;
-       }
-
-       free(key_path);
-
-       uselocale(LC_GLOBAL_LOCALE);
-       fflush(fp);
-       if (fp) {
-               ret = fdatasync(fileno(fp));
-               fclose(fp);
-       }
-
-       return 0;
-}
-
-static int _print_pref_value_from_file_path(const char *path,
-               const char *keyname)
-{
-       FILE *fp;
-       int type = 0;
-       int read_size;
-       size_t keyname_len = 0;
-       int ret;
-       int value_int = 0;
-       double value_dbl = 0;
-       char file_buf[BUF_LEN] = {0,};
-       char *value_str = NULL;
-       size_t value_size = 0;
-       size_t new_value_size = 0;
-       size_t diff;
-       size_t file_buf_size;
-       char *new_value_str;
-
-       fp = fopen(path, "r");
-       if (fp == NULL) {
-               printf("fopen() failed.(%d/%s).fp is null.\n",
-                               errno, strerror(errno));
-               return -1;
-       }
-
-       read_size = fread((void *)&keyname_len, sizeof(int), 1, fp);
-       if ((read_size <= 0) || (read_size > sizeof(int))) {
-               printf("key(%s) name length read error(%d)\n", keyname, errno);
-               fclose(fp);
-               return -1;
-       }
-
-       ret = fseek(fp, keyname_len, SEEK_CUR);
-       if (ret) {
-               printf("key(%s) name seek error(%d)\n", keyname, errno);
-               fclose(fp);
-               return -1;
-       }
-
-       /* read data type */
-       read_size = fread((void *)&type, sizeof(int), 1, fp);
-       if ((read_size <= 0) || (read_size > sizeof(int))) {
-               printf("key(%s) type read error(%d)\n", keyname, errno);
-               fclose(fp);
-               return -1;
-       }
-
-       /* read data value */
-       switch (type) {
-       case PREFERENCE_TYPE_INT:
-               read_size = fread((void *)&value_int, sizeof(int),
-                               1, fp);
-               if ((read_size <= 0) || (read_size > sizeof(int))) {
-                       if (!ferror(fp)) {
-                               printf("number of read items wrong.err: %d\n",
-                                               errno);
-                       }
-               } else {
-                       printf("[key] %s  [type] int  [value] %d\n",
-                                       keyname, value_int);
-               }
-               break;
-       case PREFERENCE_TYPE_DOUBLE:
-               read_size = fread((void *)&value_dbl, sizeof(double),
-                               1, fp);
-               if ((read_size <= 0) || (read_size > sizeof(double))) {
-                       if (!ferror(fp)) {
-                               printf("number of read items wrong.err:%d\n",
-                                               errno);
-                       }
-               } else {
-                       printf("[key] %s [type] double [value] %f\n",
-                                       keyname, value_dbl);
-               }
-               break;
-       case PREFERENCE_TYPE_BOOLEAN:
-               read_size = fread((void *)&value_int, sizeof(int),
-                               1, fp);
-               if ((read_size <= 0) || (read_size > sizeof(int))) {
-                       if (!ferror(fp)) {
-                               printf("number of read items wrong.err:%d\n",
-                                               errno);
-                       }
-               } else {
-                       printf("[key] %s [type] bool [value] %d\n",
-                                       keyname, value_int);
-               }
-               break;
-       case PREFERENCE_TYPE_STRING:
-               while (fgets(file_buf, sizeof(file_buf), fp)) {
-                       if (value_str) {
-                               file_buf_size = sizeof(file_buf);
-                               diff = INT_MAX - file_buf_size;
-                               if (value_size > diff) {
-                                       printf("Integer overflow\n");
-                                       break;
-                               }
-
-                               new_value_size = value_size + file_buf_size;
-                               new_value_str = (char *)realloc(value_str,
-                                               new_value_size);
-                               if (new_value_str == NULL)
-                                       break;
-
-                               memset(new_value_str + value_size, 0x00, sizeof(file_buf));
-                               strncat(new_value_str, file_buf, new_value_size - strlen(new_value_str));
-
-                               value_str = new_value_str;
-                               value_size = new_value_size;
-                               memset(file_buf, 0x00, sizeof(file_buf));
-                       } else {
-                               value_size = sizeof(file_buf) + 1;
-                               value_str = (char *)malloc(value_size);
-                               if (value_str == NULL)
-                                       break;
-
-                               memset(value_str, 0x00, value_size);
-                               strncpy(value_str, file_buf, value_size - 1);
-                       }
-               }
-
-               if (ferror(fp)) {
-                       printf("error, fgets() failed.\n");
-               } else {
-                       if (value_str) {
-                               printf("[key] %s [type] string [value] %s\n",
-                                               keyname, value_str);
-                       } else {
-                               printf("[key] %s [value] NULL\n", keyname);
-                       }
-               }
-               if (value_str)
-                       free(value_str);
-               break;
-       default:
-               break;
-       }
-       fclose(fp);
-
-       return 0;
-}
-
-static int _restore(const char *pkgid)
-{
-       int ret;
-       char *query;
-       sqlite3_stmt *stmt = NULL;
-       const char *tmp_key;
-       const char *tmp_type;
-       const char *tmp_value;
-
-       query = sqlite3_mprintf("SELECT * FROM %s;", PREF_TBL_NAME);
-       if (query == NULL) {
-               printf("error, query is null\n");
-               return -1;
-       }
-
-       /*prepare query*/
-       ret = sqlite3_prepare_v2(pref_db, query, strlen(query), &stmt, NULL);
-       sqlite3_free(query);
-       if (ret != SQLITE_OK) {
-               printf("error, sqlite3_prepare_v2 failed(%d)\n", ret);
-               return -1;
-       }
-
-       while (1) {
-               ret = sqlite3_step(stmt);
-               if (ret == SQLITE_ROW) {
-                       tmp_key = (const char *)sqlite3_column_text(stmt, 0);
-                       tmp_type = (const char *)sqlite3_column_text(stmt, 1);
-                       tmp_value = (const char *)sqlite3_column_text(stmt, 2);
-
-                       printf("col[key]:%s\ncol[type]:%s\ncol[value]:%s\n",
-                                       tmp_key, tmp_type, tmp_value);
-
-                       /*key create*/
-                       ret = _create_new_preference_key(PREFERENCE_OP_RESTORE,
-                                       pkgid, tmp_key, tmp_type, tmp_value);
-                       if (ret < 0) {
-                               printf("create new prefer key failed (%d)\n",
-                                               ret);
-                               sqlite3_finalize(stmt);
-                               return -1;
-                       }
-               } else {
-                       break;
-               }
-       }
-       sqlite3_finalize(stmt);
-
-       return 0;
-}
-
-
-static int _remove_old_db(const char *db_path)
-{
-       int ret;
-       char journal_path[PATH_MAX];
-       char *path = strdup(db_path);
-
-       if (!path) {
-               printf("error, strdup(): Insufficient memory available\n");
-               return -1;
-       }
-
-       ret = remove(path);
-       if (ret < 0) {
-               printf("error, remove(%d/%s)\n", errno, strerror(errno));
-               free(path);
-               return -1;
-       }
-
-       snprintf(journal_path, sizeof(journal_path), "%s-journal", path);
-
-       if (access(journal_path, F_OK) == 0) {
-               ret = remove(journal_path);
-               if (ret < 0) {
-                       printf("error, remove(%d/%s)\n", errno,
-                                               strerror(errno));
-                       free(path);
-                       return -1;
-               }
-       }
-       free(path);
-
-       return 0;
-}
-
-static void _print_help(void)
-{
-       printf("\n[Set preference value]\n");
-       printf("preference_tool set <pkgid> <key_name> <type> <value>\n");
-       printf("ex) preference_tool set ");
-       printf("org.tizen.preferencetest test_key string value\n\n");
-
-       printf("[Get preference value]\n");
-       printf("preference_tool get <pkgid>\n");
-       printf("ex) preference_tool get org.tizen.preferencetest\n\n");
-       printf("preference_tool get <pkgid> <key>\n");
-       printf("ex) preference_tool get ");
-       printf("org.tizen.preferencetest test_key\n\n");
-
-       printf("[Convert preference file name from plain text]\n");
-       printf("preference_tool convert_file_name <app_dir>\n");
-       printf("ex) preference_tool convert_file_name /opt/usr/apps\n\n");
-}
-
-static void _preference_set_key(const char *pkgid, const char *key,
-               const char *type, const char *value)
-{
-       _create_new_preference_key(PREFERENCE_OP_NEW_CREATE,
-                       pkgid, key, type, value);
-}
-
-static void _print_preference_key(const char *pkgid, const char *key)
-{
-       char *key_path;
-
-       _make_key_path(pkgid, key, &key_path);
-       _print_pref_value_from_file_path(key_path, key);
-
-       free(key_path);
-}
-
-static void _print_preference_in_package(const char *pkgid)
-{
-       char pref_dir[PATH_MAX];
-       DIR *dir;
-       int dfd, res, size;
-       struct stat st;
-       struct dirent *ent = NULL;
-       const char *name;
-       char *keyname = NULL;
-       char *file_full_path;
-       const char *pkg_path;
-
-       pkg_path = __get_package_path(pkgid);
-       if (pkg_path == NULL)
-               return;
-
-       snprintf(pref_dir, sizeof(pref_dir), "%s/data/.pref", pkg_path);
-
-       dir = opendir(pref_dir);
-       if (dir == NULL) {
-               printf("Is not exist preference key in %s.\n", pkgid);
-               return;
-       }
-
-       dfd = dirfd(dir);
-       res = fstat(dfd, &st);
-       if (res < 0) {
-               printf("fstat() failed. path: %s, errno: %d(%s)\n",
-                               pref_dir, errno, strerror(errno));
-               closedir(dir);
-               return;
-       }
-
-       while ((ent = readdir(dir))) {
-               name = ent->d_name;
-               if (name[0] == '.') {
-                       if (name[1] == '\0')
-                               continue;
-                       if ((name[1] == '.') && (name[2] == '\0'))
-                               continue;
-               }
-
-               size = 1 + snprintf(0, 0, "%s/%s", pref_dir, name);
-               file_full_path = (char *)malloc(size);
-               if (file_full_path == NULL) {
-                       printf("Out of memory\n");
-                       closedir(dir);
-                       return;
-               }
-
-               snprintf(file_full_path, size, "%s/%s", pref_dir, name);
-               _get_key_name(file_full_path, &keyname);
-               _print_pref_value_from_file_path(file_full_path, keyname);
-               free(file_full_path);
-               if (keyname) {
-                       free(keyname);
-                       keyname = NULL;
-               }
-       }
-       closedir(dir);
-}
-
-static void write_history(const char *str)
-{
-       FILE *fp = NULL;
-       int ret = 0;
-
-       fp = fopen(HISTORY, "a");
-       if (fp == NULL) {
-               printf("fopen() failed. FOTA history log (%d/%s)",
-                               errno, strerror(errno));
-               return;
-       }
-
-       ret = fwrite((void *)str, strlen(str) + 1, 1, fp);
-       if (ret <= 0) {
-               printf("fwrite() failed. FOTA history log (%d/%s)",
-                               errno, strerror(errno));
-       }
-       fclose(fp);
-}
-
-static int _add_key_info_to_file(const char *key_path, const char *key)
-{
-       FILE *fp = NULL;
-       size_t keyname_len;
-       char *buf = NULL;
-       int read_size;
-       int ret;
-       long file_size;
-
-       fp = fopen(key_path, "r+");
-       if (fp == NULL) {
-               printf("fopen() failed.(%d/%s).fp is null.\n",
-                               errno, strerror(errno));
-               return -1;
-       }
-
-       ret = fseek(fp, 0, SEEK_END);
-       if (ret == -1) {
-               printf("failed to fseek.(%d/%s)\n", errno, strerror(errno));
-               ret = -1;
-               goto out;
-       }
-
-       file_size = ftell(fp);
-       if (file_size == -1) {
-               printf("failed to ftell.(%d/%s)\n", errno, strerror(errno));
-               ret = -1;
-               goto out;
-       }
-
-       rewind(fp);
-
-       buf = (char *)calloc(1, file_size);
-       if (buf == NULL) {
-               printf("Out of memory\n");
-               ret = -1;
-               goto out;
-       }
-
-       /* write keyname and size */
-       read_size = fread(buf, 1, file_size, fp);
-       if ((read_size <= 0)) {
-               printf("preference read key-val data error(%d/%s)\n",
-                               errno, strerror(errno));
-               ret = -1;
-               goto out;
-       }
-
-       rewind(fp);
-
-       keyname_len = strlen(key);
-       ret = fwrite((void *)&keyname_len, sizeof(int), 1, fp);
-       if (ret <= 0) {
-               printf("preference write key name length error(%d/%s)\n",
-                                               errno, strerror(errno));
-               ret = -1;
-               goto out;
-       }
-
-       ret = fwrite((void *)key, keyname_len, 1, fp);
-       if (ret <= 0) {
-               printf("preference write key name error(%d/%s)\n",
-                                               errno, strerror(errno));
-               ret = -1;
-               goto out;
-       }
-       ret = fwrite((void *)buf, read_size, 1, fp);
-       if (ret <= 0) {
-               printf("preference write key-val data error(%d/%s)\n",
-                                               errno, strerror(errno));
-               ret = -1;
-               goto out;
-       }
-
-       ret = 0;
-
-out:
-       if (fp)
-               fclose(fp);
-       if (buf)
-               free(buf);
-
-       return ret;
-}
-
-static int _convert_pref_file(const char *pref_dir)
-{
-       DIR *dir;
-       struct dirent *ent;
-       char *old_file;
-       char *new_file;
-       gchar *convert_key;
-       char _key[PREFERENCE_KEY_PATH_LEN] = {0,};
-       char *chrptr = NULL;
-       int size;
-
-       dir = opendir(pref_dir);
-       if (!dir)
-               return -1;
-
-       while ((ent = readdir(dir))) {
-               if (ent->d_type != DT_REG)
-                       continue;
-
-               size = 1 + snprintf(0, 0, "%s/%s", pref_dir, ent->d_name);
-               old_file = (char *)malloc(size);
-               if (old_file == NULL) {
-                       printf("Out of memory\n");
-                       closedir(dir);
-                       return -1;
-               }
-
-               snprintf(old_file, size, "%s/%s", pref_dir, ent->d_name);
-
-               strncpy(_key, ent->d_name, PREFERENCE_KEY_PATH_LEN - 1);
-
-               chrptr = strchr((const char*)_key, DELIMITER);
-               if (chrptr) {
-                       chrptr = strchr((const char*)_key, DELIMITER);
-                       while (chrptr) {
-                               _key[chrptr-_key] = '/';
-                               chrptr = strchr((const char*)chrptr + 1, DELIMITER);
-                       }
-               }
-
-               convert_key = g_compute_checksum_for_string(G_CHECKSUM_SHA1,
-                               _key, strlen(_key));
-               if (convert_key == NULL) {
-                       printf("fail to convert key\n");
-                       free(old_file);
-                       closedir(dir);
-                       return -1;
-               }
-
-
-               size = 1 + snprintf(0, 0, "%s/%s", pref_dir, convert_key);
-               new_file = (char *)malloc(size);
-               if (new_file == NULL) {
-                       printf("Out of memory\n");
-                       free(old_file);
-                       g_free(convert_key);
-                       closedir(dir);
-                       return -1;
-               }
-
-               snprintf(new_file, size, "%s/%s", pref_dir, convert_key);
-
-               g_free(convert_key);
-
-               if (rename(old_file, new_file) < 0) {
-                       printf("rename %s to %s failed.(%d/%s)\n",
-                                       old_file, new_file,
-                                       errno, strerror(errno));
-               }
-
-               if (_add_key_info_to_file(new_file, _key) < 0)
-                       printf("convert %s file failed\n", new_file);
-
-               free(old_file);
-               free(new_file);
-       }
-
-       closedir(dir);
-       return 0;
-}
-
-static int _convert_file_name(const char *app_dir)
-{
-       DIR *dir;
-       struct dirent *ent;
-       char buf[BUF_LEN];
-       int res;
-
-       dir = opendir(app_dir);
-       if (!dir) {
-               printf("failed to open app dir (%s)\n", app_dir);
-               return -1;
-       }
-
-       while ((ent = readdir(dir))) {
-               if (ent->d_type != DT_DIR)
-                       continue;
-
-               if (strcmp(ent->d_name, ".") == 0 ||
-                               strcmp(ent->d_name, "..") == 0)
-                       continue;
-
-               snprintf(buf, sizeof(buf), "%s/%s/data/.pref",
-                               app_dir, ent->d_name);
-               if (access(buf, F_OK) == -1)
-                       continue;
-
-               res = _convert_pref_file(buf);
-               if (res < 0) {
-                       printf("_convert_pref_file error (%s)\n", buf);
-                       closedir(dir);
-                       return -1;
-               }
-       }
-
-       closedir(dir);
-       return 0;
-}
-
-int main(int argc, char *argv[])
-{
-       int res;
-
-       if (getuid() != 0) {
-               printf("[pref] Only root user can use.\n");
-               return -1;
-       }
-
-       if (argc < 3) {
-               _print_help();
-               return -1;
-       }
-
-       if (strcmp(argv[1], "restore") == 0 && argc == 4) {
-               printf("[ start ] ----------------------------------------\n");
-               printf("Db file path:%s\n\n", argv[2]);
-
-               res = _initialize(argv[2]);
-               if (res < 0) {
-                       printf("failed. _initialize(%d)\n", res);
-                       return -1;
-               }
-
-               res = _restore(argv[3]);
-               if (res < 0) {
-                       printf("failed. _restore(%d)\n", res);
-                       write_history("\t\t- restore failed.\n");
-                       printf("restore failed.\n");
-                       return -1;
-               }
-
-               res = _remove_old_db(argv[2]);
-               if (res < 0) {
-                       printf("failed. _remove_old_db(%d)\n", res);
-                       return -1;
-               }
-
-               printf("-------------------------------------------------\n");
-               printf("done\n\n");
-               write_history("\t\t+ restore success.\n");
-       } else if (strcmp(argv[1], "get") == 0 || strcmp(argv[1], "GET") == 0) {
-               if (is_exist_package(argv[2]) < 0)
-                       return -1;
-
-               if (is_exist_data_dir_in_package(argv[2]) < 0)
-                       return -1;
-
-               if (argc > 3 && argv[3])
-                       _print_preference_key(argv[2], argv[3]);
-               else
-                       _print_preference_in_package(argv[2]);
-       } else if (strcmp(argv[1], "set") == 0 || strcmp(argv[1], "SET") == 0) {
-               if (is_exist_package(argv[2]) < 0)
-                       return -1;
-
-               if (is_exist_data_dir_in_package(argv[2]) < 0)
-                       return -1;
-
-               if (argv[2] && argv[3] && argv[4] && argv[5])
-                       _preference_set_key(argv[2], argv[3], argv[4], argv[5]);
-               else
-                       _print_help();
-       } else if (strcmp(argv[1], "convert_file_name") == 0) {
-               res = _convert_file_name(argv[2]);
-
-               if (res < 0) {
-                       printf("converting preference file name failed (%s)\n",
-                                       argv[2]);
-                       return -1;
-               }
-       } else {
-               _print_help();
-       }
-
-       return 0;
-}
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a12f918
--- /dev/null
@@ -0,0 +1,25 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TOOL_SRCS)
+
+ADD_EXECUTABLE(${TARGET_TOOL} ${TOOL_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_TOOL} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+APPLY_PKG_CONFIG(${TARGET_TOOL} PUBLIC
+  CAPI_BASE_COMMON_DEPS
+  DLOG_DEPS
+  LIBTZPLATFORM_CONFIG_DEPS
+  PKGMGR_INFO_DEPS
+  SQLITE3_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_TOOL} PUBLIC ${TARGET_PREFERENCE})
+SET_TARGET_PROPERTIES(${TARGET_TOOL} PROPERTIES COMPILE_FLAGS
+  ${CFLAGS} "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_TOOL} PROPERTIES LINK_FLAGS
+  "-Wl,--rpath=${LIBDIR} -pie")
+
+INSTALL(TARGETS ${TARGET_TOOL}
+  DESTINATION ${BINDIR})
+INSTALL(FILES pref_dump.sh
+  DESTINATION /opt/etc/dump.d/module.d)
diff --git a/tool/log-private.hh b/tool/log-private.hh
new file mode 100644 (file)
index 0000000..d309fdd
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 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 TOOL_LOG_PRIVATE_HH_
+#define TOOL_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "PREFERENCE_TOOL"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // TOOL_LOG_PRIVATE_HH_
diff --git a/tool/pref_dump.sh b/tool/pref_dump.sh
new file mode 100644 (file)
index 0000000..ddf80ef
--- /dev/null
@@ -0,0 +1,17 @@
+#!/bin/sh
+PATH="/usr/bin:/bin:/usr/sbin:/sbin"
+
+PREF_DUMP=$1/pref
+/bin/mkdir -p $PREF_DUMP
+
+for file in `/usr/bin/find /opt/usr/home/owner/apps_rw/ -name *.pref`
+do
+       chsmack $file >> $PREF_DUMP/pref_value
+       chsmack $file/* >> $PREF_DUMP/pref_value
+       ls -alZ $file >> $PREF_DUMP/pref_value
+       PKG_ID=`echo "$file" | awk -F'/' '{print $5}'`
+       /usr/bin/preference_tool get $PKG_ID >> $PREF_DUMP/pref_value
+       mkdir -p $PREF_DUMP/$PKG_ID
+       cp -rf --preserve=all $file/* $PREF_DUMP/$PKG_ID
+       echo "===============================================" >> $PREF_DUMP/pref_value
+done
diff --git a/tool/preference_tool.cc b/tool/preference_tool.cc
new file mode 100644 (file)
index 0000000..ceaa6da
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2011 - 2021 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 <dirent.h>
+#include <errno.h>
+#include <grp.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <tzplatform_config.h>
+#include <unistd.h>
+#include <wordexp.h>
+
+#include <iostream>
+#include <string>
+
+#include "preference/file-internal.hh"
+#include "tool/log-private.hh"
+
+namespace {
+using namespace preference::internal;
+
+class PrefTool {
+ private:
+  PrefTool() = default;
+  ~PrefTool() = default;
+
+ public:
+  static PrefTool& GetInst();
+  void PrintHelp();
+  void Set(const std::string& pkg_id, const std::string& key,
+      const std::string& type, const std::string& value);
+  void Get(const std::string& pkg_id);
+  void Get(const std::string& pkg_id, const std::string& key);
+  void GetAll();
+
+ private:
+  std::string GetPrefPath(const std::string& pkg_id);
+  int CreateDirectory(const std::string& path);
+  int ChangeOwner(const std::string& path);
+  int ChangeMode(const std::string& path, mode_t mode);
+  int ChangeSmack(const std::string& pkg_id, const std::string& path,
+      bool transmute = true);
+  gid_t GetGid(const std::string& name);
+  Data::Type ConvertType(const std::string& type);
+  std::string GetTypeName(Data::Type type);
+  void PrintData(const Data& data);
+};
+
+PrefTool& PrefTool::GetInst() {
+  static PrefTool inst;
+  return inst;
+}
+
+void PrefTool::PrintHelp() {
+  std::cout << "[Set preference value]"
+            << std::endl;
+  std::cout << "$ preference_tool set <pkgid> <key_name> <type> <value>"
+            << std::endl;
+  std::cout << "ex) preference_tool set org.tizen.helloworld key string value"
+            << std::endl;
+  std::cout << std::endl;
+
+  std::cout << "[Get preference value]"
+            << std::endl;
+  std::cout << "$ preference_tool get <pkgid>"
+            << std::endl;
+  std::cout << "ex) preference_tool get org.tizen.helloworld"
+            << std::endl;
+  std::cout << std::endl;
+
+  std::cout << "$ preference_tool get <pkgid> <key>"
+            << std::endl;
+  std::cout << "ex) preference_tool get org.tizen.helloworld key"
+            << std::endl;
+  std::cout << std::endl;
+
+  std::cout << "[Get all preference values]"
+            << std::endl;
+  std::cout << "$ preference_tool get_all"
+            << std::endl;
+  std::cout << "ex) preference_tool get_all"
+            << std::endl;
+  std::cout << std::endl;
+}
+
+void PrefTool::Set(const std::string& pkg_id, const std::string& key,
+    const std::string& type, const std::string& value) {
+  std::string pref_path = GetPrefPath(pkg_id);
+  if (access(pref_path.c_str(), F_OK) < 0) {
+    if (CreateDirectory(pref_path) < 0)
+      return;
+
+    if (ChangeOwner(pref_path) < 0)
+      return;
+
+    if (ChangeSmack(pkg_id, pref_path) < 0)
+      return;
+  }
+
+  Data::Type data_type = ConvertType(type);
+  if (data_type == Data::Type::NONE) {
+    fprintf(stderr, "Invalid type. type(%d)\n", static_cast<int>(data_type));
+    return;
+  }
+
+  Data data(key);
+  if (data_type == Data::Type::STRING) {
+    data.SetString(value.c_str());
+  } else if (data_type == Data::Type::INT) {
+    data.SetInt(std::stoi(value));
+  } else if (data_type == Data::Type::DOUBLE) {
+    data.SetDouble(std::stod(value));
+  } else {
+    if (value == "ture" || value == "1")
+      data.SetBoolean(true);
+    else
+      data.SetBoolean(false);
+  }
+
+  File file(key, pref_path);
+  file.SetData(data);
+  int ret = file.Write();
+  if (ret != 0) {
+    fprintf(stderr, "Write() is failed. key(%s), type(%s), value(%s), "
+        "error(%d)\n", key.c_str(), type.c_str(), value.c_str(), ret);
+    return;
+  }
+  file.Close();
+
+  ChangeOwner(file.GetPath());
+  ChangeMode(file.GetPath(), 0660);
+  ChangeSmack(pkg_id, file.GetPath(), false);
+  Get(pkg_id, key);
+}
+
+void PrefTool::Get(const std::string& pkg_id, const std::string& key) {
+  std::string pref_path = GetPrefPath(pkg_id);
+  File file(key, pref_path);
+  int ret = file.Read();
+  if (ret != 0) {
+    fprintf(stderr, "Read() is failed. pkg_id(%s), key(%s), error(%d)\n",
+        pkg_id.c_str(), key.c_str(), ret);
+    return;
+  }
+
+  Data data = file.GetData();
+  PrintData(data);
+}
+
+void PrefTool::Get(const std::string& pkg_id) {
+  std::string pref_path = GetPrefPath(pkg_id);
+  if (access(pref_path.c_str(), F_OK) != 0) {
+    return;
+  }
+
+  DIR* dp = opendir(pref_path.c_str());
+  if (dp == nullptr) {
+    fprintf(stderr, "opendir(%s) is failed. errno(%d)\n",
+        pref_path.c_str(), errno);
+    return;
+  }
+
+  printf("[%s]\n", pkg_id.c_str());
+  struct dirent* dentry;
+  while ((dentry = readdir(dp)) != nullptr) {
+    const char* name = dentry->d_name;
+    if (!strcmp(name, ".") || !strcmp(name, ".."))
+      continue;
+
+    File file(name, pref_path, true);
+    int ret = file.Read();
+    if (ret != 0) {
+      fprintf(stderr, "Read() is failed. pkg_id(%s), key(%s), error(%d)\n",
+          pkg_id.c_str(), name, ret);
+      break;
+    }
+
+    Data data = file.GetData();
+    PrintData(data);
+  }
+  printf("=================================================================\n");
+  closedir(dp);
+}
+
+void PrefTool::GetAll() {
+  uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+  tzplatform_set_user(uid);
+  const char* path = tzplatform_getenv(TZ_USER_APP);
+  tzplatform_reset_user();
+  DIR* dp = opendir(path);
+  if (dp == nullptr) {
+    fprintf(stderr, "opendir(%s) is failed. errno(%d)\n", path, errno);
+    return;
+  }
+
+  struct dirent* dentry;
+  while ((dentry = readdir(dp)) != nullptr) {
+    const char* name = dentry->d_name;
+    if (!strcmp(name, ".") || !strcmp(name, ".."))
+      continue;
+
+    Get(name);
+  }
+  closedir(dp);
+}
+
+std::string PrefTool::GetPrefPath(const std::string& pkg_id) {
+  uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+  tzplatform_set_user(uid);
+  const char* path = tzplatform_mkpath(TZ_USER_APP, pkg_id.c_str());
+  tzplatform_reset_user();
+  if (path == nullptr) {
+    std::cerr << "tzplatform_mkpath() is failed" << std::endl;
+    return {};
+  }
+
+  return std::string(path) + "/data/.pref";
+}
+
+int PrefTool::CreateDirectory(const std::string& path) {
+  mode_t mode = 0664 | 0111;
+  int ret = mkdir(path.c_str(), mode);
+  if (ret != 0) {
+    fprintf(stderr, "mkdir(%s, %d) is failed. errno(%d)\n",
+        path.c_str(), mode, errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+int PrefTool::ChangeOwner(const std::string& path) {
+  uid_t uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+  gid_t gid = GetGid("system_share");
+  int ret = chown(path.c_str(), uid, gid);
+  if (ret != 0) {
+    fprintf(stderr, "chown(%s, %u, %u) is failed. errno(%d)\n",
+        path.c_str(), uid, gid, errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+int PrefTool::ChangeMode(const std::string& path, mode_t mode) {
+  int ret = chmod(path.c_str(), mode);
+  if (ret != 0) {
+    fprintf(stderr, "chmod(%s, %d) is failed. errno(%d)\n",
+        path.c_str(), mode, errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+int PrefTool::ChangeSmack(const std::string& pkg_id, const std::string& path,
+    bool transmute) {
+  std::string option = transmute ? "-t" : " ";
+  std::string command = "/usr/bin/chsmack " + option + " -a User::Pkg::" +
+      pkg_id + " " + path;
+  pid_t pid = fork();
+  if (pid == -1) {
+    perror("fork() is failed\n");
+    return -1;
+  }
+
+  if (pid == 0) {
+    wordexp_t p;
+    wordexp(command.c_str(), &p, 0);
+    char** w = p.we_wordv;
+    int ret = execv(w[0], const_cast<char* const*>(w));
+    wordfree(&p);
+    exit(ret);
+  } else {
+    int status;
+    if (waitpid(pid, &status, 0) == -1) {
+      perror("waitpid() is failed\n");
+      return -1;
+    }
+
+    if (WIFSIGNALED(status)) {
+      fprintf(stderr, "signal(%d)\n", WTERMSIG(status));
+      perror("exit by signal\n");
+      return -1;
+    }
+
+    if (!WIFEXITED(status)) {
+      perror("exit abnormally\n");
+      return -1;
+    }
+
+    if (WIFEXITED(status) && WEXITSTATUS(status)) {
+      perror("child process returns an error\n");
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+gid_t PrefTool::GetGid(const std::string& name) {
+  struct group entry;
+  struct group* ge = nullptr;
+  char buf[LINE_MAX];
+  int ret = getgrnam_r(name.c_str(), &entry, buf, sizeof(buf), &ge);
+  if (ret != 0) {
+    fprintf(stderr, "getgrnam_r() is failed. errno(%d)\n", errno);
+    return -1;
+  }
+
+  return entry.gr_gid;
+}
+
+Data::Type PrefTool::ConvertType(const std::string& type) {
+  if (type == "string")
+    return Data::Type::STRING;
+
+  if (type == "int")
+    return Data::Type::INT;
+
+  if (type == "double")
+    return Data::Type::DOUBLE;
+
+  if (type == "boolean" || type == "bool")
+    return Data::Type::BOOLEAN;
+
+  return Data::Type::NONE;
+}
+
+std::string PrefTool::GetTypeName(Data::Type type) {
+  if (type == Data::Type::STRING)
+    return "string";
+  if (type == Data::Type::INT)
+    return "integer";
+  if (type == Data::Type::DOUBLE)
+    return "double";
+  if (type == Data::Type::BOOLEAN)
+    return "boolean";
+
+  return "none";
+}
+
+void PrefTool::PrintData(const Data& data) {
+  auto type = data.GetType();
+  printf("[key] %s [type] %s [value] ",
+      data.GetKey().c_str(), GetTypeName(type).c_str());
+  if (type == Data::Type::STRING)
+    printf("%s\n", data.GetString());
+  else if (type == Data::Type::INT)
+    printf("%d\n", data.GetInt());
+  else if (type == Data::Type::DOUBLE)
+    printf("%f\n", data.GetDouble());
+  else
+    printf("%s\n", data.GetBoolean() ? "true" : "false");
+}
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  if (getuid() != 0) {
+    std::cerr << "[pref] Only root user can use." << std::endl;
+    return -1;
+  }
+
+  if (argc < 2) {
+    ::PrefTool::GetInst().PrintHelp();
+    return -1;
+  }
+
+  int ret = 0;
+  if (!strcasecmp(argv[1], "set")) {
+    if (argc > 5)
+      ::PrefTool::GetInst().Set(argv[2], argv[3], argv[4], argv[5]);
+    else
+      ret = -1;
+  } else if (!strcasecmp(argv[1], "get")) {
+    if (argc > 3)
+      ::PrefTool::GetInst().Get(argv[2], argv[3]);
+    else if (argc > 2)
+      ::PrefTool::GetInst().Get(argv[2]);
+    else
+      ret = -1;
+  } else if (!strcasecmp(argv[1], "get_all")) {
+    ::PrefTool::GetInst().GetAll();
+  } else {
+    ret = -1;
+  }
+
+  if (ret == -1)
+    ::PrefTool::GetInst().PrintHelp();
+
+  return 0;
+}
index 93444f8d3bc4d88c0d95e32dbd1373de5d8d2eaa..2682162408169ab3e82522328d886797c56c2846 100644 (file)
@@ -1,20 +1,28 @@
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TEST_SRCS)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock MOCK_SRCS)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
 
-ENABLE_TESTING()
+INCLUDE_DIRECTORIES(${TARGET_UNIT_TESTS} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../include/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../preference/
+)
 
-SET(TARGET_TEST "preference-test")
-ADD_EXECUTABLE(${TARGET_TEST} ${TEST_SRCS} ${MOCK_SRCS})
-ADD_TEST(${TARGET_TEST} ${TARGET_TEST})
+ADD_EXECUTABLE(${TARGET_UNIT_TESTS}
+  ${MOCK_SRCS}
+  ${TEST_SRCS}
+)
 
-INCLUDE(FindPkgConfig)
-pkg_check_modules(test REQUIRED dlog glib-2.0 capi-appfw-app-common)
-FOREACH(flag ${test_CFLAGS})
-    SET(EXTRA_CXXFLAGS_test "${EXTRA_CXXFLAGS_test} ${flag}")
-ENDFOREACH(flag)
+ADD_TEST(${TARGET_UNIT_TESTS} ${TARGET_UNIT_TESTS})
 
-SET(${EXTRA_CXXFLAGS_test} "${EXTRA_CXXFLAGS_test} --std=c++14")
-SET_TARGET_PROPERTIES(${TARGET_TEST} PROPERTIES COMPILE_FLAGS ${EXTRA_CXXFLAGS_test})
+APPLY_PKG_CONFIG(${TARGET_UNIT_TESTS} PUBLIC
+  CAPI_APPFW_APP_COMMON_DEPS
+  DLOG_DEPS
+  GLIB_DEPS
+  GMOCK_DEPS
+)
 
-TARGET_LINK_LIBRARIES(${TARGET_TEST} gmock capi-appfw-preference pthread)
\ No newline at end of file
+TARGET_LINK_LIBRARIES(${TARGET_UNIT_TESTS} PUBLIC ${TARGET_PREFERENCE} pthread)
+SET_TARGET_PROPERTIES(${TARGET_UNIT_TESTS} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_UNIT_TESTS} PROPERTIES LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_UNIT_TESTS} DESTINATION bin)
diff --git a/unittests/main.cc b/unittests/main.cc
new file mode 100644 (file)
index 0000000..bcb21a6
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020 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 <gmock/gmock.h>
+
+int main(int argc, char* argv[]) {
+  int ret = 0;
+  try {
+    ::testing::InitGoogleTest(&argc, argv);
+  } catch(...) {
+    std::cout << "Exception occured" << std::endl;
+    return 1;
+  }
+
+  try {
+    return RUN_ALL_TESTS();
+  } catch(const ::testing::internal::GoogleTestFailureException& e) {
+    std::cout << "GoogleTestFailureException occured:" << e.what() << std::endl;
+    ret = 1;
+  }
+
+  return ret;
+}
index 7f4a2c5307f5528a115c65d658f103c156b69dce..df44be4e33ecbbb72ffc11ab447bec420281a212 100644 (file)
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#include "common_mock.h"
-#include "mock_hook.h"
-#include "test_fixture.h"
+#include "unittests/mock/common_mock.h"
+#include "unittests/mock/mock_hook.h"
+#include "unittests/mock/test_fixture.h"
 
 extern "C" char* app_get_data_path() {
   return MOCK_HOOK_P0(CommonMock, app_get_data_path);
index 408a7dafc6dc9c1daa59ba109246da529973ae73..2fe155fa89bc7ac99aa5a60d9aebf44ce021d0fc 100644 (file)
  * limitations under the License.
  */
 
-#ifndef MOCK_COMMON_MOCK_H_
-#define MOCK_COMMON_MOCK_H_
+#ifndef UNITTESTS_MOCK_COMMON_MOCK_H_
+#define UNITTESTS_MOCK_COMMON_MOCK_H_
+
 #include <gmock/gmock.h>
 
-#include "module_mock.h"
+#include "unittests/mock/module_mock.h"
 
 class CommonMock : public virtual ModuleMock {
  public:
@@ -27,4 +28,4 @@ class CommonMock : public virtual ModuleMock {
   MOCK_METHOD0(app_get_data_path, char*());
 };
 
-#endif  // MOCK_COMMON_HOOK_H_
+#endif  // UNITTESTS_MOCK_COMMON_MOCK_H_
index 79831d7d9e16b701c9de2f8610fd1ffa262e5d19..035a29a74ae1ca640e1c5e0026cdd973f21d57ab 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef MOCK_MOCK_HOOK_H_
-#define MOCK_MOCK_HOOK_H_
+#ifndef UNITTESTS_MOCK_MOCK_HOOK_H_
+#define UNITTESTS_MOCK_MOCK_HOOK_H_
 
 #define MOCK_HOOK_P0(MOCK_CLASS, f)                                            \
     TestFixture::GetMock<MOCK_CLASS>().f()
@@ -39,4 +39,4 @@
     TestFixture::GetMock<MOCK_CLASS>().f(                                      \
         p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
 
-#endif  // MOCK_MOCK_HOOK_H_
+#endif  // UNITTESTS_MOCK_MOCK_HOOK_H_
index 0934014d151397c927539ada26b9ee6b0fb07fc7..fce1caca995dec3ba18012af279fdfd033e03f44 100644 (file)
  * limitations under the License.
  */
 
-#ifndef MOCK_MODULE_MOCK_H_
-#define MOCK_MODULE_MOCK_H_
+#ifndef UNITTESTS_MOCK_MODULE_MOCK_H_
+#define UNITTESTS_MOCK_MODULE_MOCK_H_
 
 class ModuleMock {
  public:
   virtual ~ModuleMock() {}
 };
 
-#endif  // MOCK_MODULE_MOCK_H_
+#endif  // UNITTESTS_MOCK_MODULE_MOCK_H_
index 4a77054487f7be498f87fad68e221b4e1aed41a6..d1567599e8500a68fafc8a8de5873b651611907b 100644 (file)
@@ -16,6 +16,6 @@
 
 #include <memory>
 
-#include "test_fixture.h"
+#include "unittests/mock/test_fixture.h"
 
 std::unique_ptr<ModuleMock> TestFixture::mock_;
index db223f184dd06e8b1ef38ba14d31fb2cbeae177e..2fe4f5f999dd13308401a070cc6b1c9f04952306 100644 (file)
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef MOCK_TEST_FIXTURE_H_
-#define MOCK_TEST_FIXTURE_H_
+#ifndef UNITTESTS_MOCK_TEST_FIXTURE_H_
+#define UNITTESTS_MOCK_TEST_FIXTURE_H_
 
 #include <gtest/gtest.h>
 
@@ -24,7 +24,7 @@
 #include <string>
 #include <utility>
 
-#include "module_mock.h"
+#include "unittests/mock/module_mock.h"
 
 class TestFixture : public ::testing::Test {
  public:
@@ -50,4 +50,4 @@ class TestFixture : public ::testing::Test {
   static std::unique_ptr<ModuleMock> mock_;
 };
 
-#endif  // MOCK_TEST_FIXTURE_H_
+#endif  // UNITTESTS_MOCK_TEST_FIXTURE_H_
index e4993f06ceb3fab7bb1aec39ae50c44999198e1e..0b9b7a15221c218ef9d35696c65bc38b872c608c 100644 (file)
  * limitations under the License.
  */
 
-#include <string.h>
-
-#include <functional>
-
 #include <app_preference.h>
 #include <dlog.h>
 #include <glib.h>
 #include <gmock/gmock.h>
+#include <string.h>
+
+#include <functional>
 
-#include "mock/common_mock.h"
-#include "mock/test_fixture.h"
+#include "unittests/mock/common_mock.h"
+#include "unittests/mock/test_fixture.h"
 
-extern "C" int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...) {
+extern "C" int __dlog_print(log_id_t log_id, int prio, const char* tag,
+    const char* fmt, ...) {
   printf("%s:", tag);
   va_list ap;
   va_start(ap, fmt);
   vprintf(fmt, ap);
   va_end(ap);
   printf("\n");
-
   return 0;
 }
 
@@ -80,21 +79,21 @@ TEST_F(PreferenceTest, Basic) {
   }));
 
   ret = preference_set_int("testint", 0);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_get_int("testint", &intval);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_set_double("testdouble", 0.0f);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_get_double("testdouble", &doubleval);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_set_string("teststring", "test");
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_get_string("teststring", &strval);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_set_boolean("testboolean", false);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   ret = preference_get_boolean("testboolean", &boolval);
-  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR));
+  EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
 
   EXPECT_CALL(GetMock<CommonMock>(), app_get_data_path())
       .WillRepeatedly(testing::Invoke([&]() {
@@ -242,15 +241,17 @@ TEST_F(PreferenceTest, Callback) {
   ret = preference_set_int("test1", 0);
   EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   bool called = false;
-  ret = preference_set_changed_cb("test1", [](const char* key, void* user_data) {
-    bool* called = reinterpret_cast<bool*>(user_data);
-    *called = true;
-  }, reinterpret_cast<bool*>(&called));
+  ret = preference_set_changed_cb("test1",
+      [](const char* key, void* user_data) {
+        bool* called = reinterpret_cast<bool*>(user_data);
+        *called = true;
+      }, reinterpret_cast<bool*>(&called));
   EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   EXPECT_THAT(called, testing::Eq(false));
 
   ret = preference_set_int("test1", 1);
-  while (g_main_context_iteration(g_main_context_default(), true));
+  while (g_main_context_iteration(g_main_context_default(), true)) {
+  }
 
   EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   EXPECT_THAT(called, testing::Eq(true));
@@ -260,7 +261,9 @@ TEST_F(PreferenceTest, Callback) {
   EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
 
   ret = preference_set_int("test1", 1);
-  while (g_main_context_iteration(g_main_context_default(), true));
+  while (g_main_context_iteration(g_main_context_default(), true)) {
+  }
+
   EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
   EXPECT_THAT(called, testing::Eq(false));
 
@@ -274,23 +277,4 @@ TEST_F(PreferenceTest, Callback) {
   EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE));
 }
 
-} //  namespace
-
-int main(int argc, char* argv[]) {
-  int ret = 0;
-  try {
-    ::testing::InitGoogleTest(&argc, argv);
-  } catch(...) {
-    std::cout << "Exception occured" << std::endl;
-    return 1;
-  }
-
-  try {
-    return RUN_ALL_TESTS();
-  } catch(const ::testing::internal::GoogleTestFailureException& e) {
-    std::cout << "GoogleTestFailureException occured:" << e.what() << std::endl;
-    ret = 1;
-  }
-
-  return ret;
-}
+}  // namespace preference
diff --git a/unittests/preference_unittest.cc b/unittests/preference_unittest.cc
new file mode 100644 (file)
index 0000000..5026c25
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2021 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 <app_preference.h>
+#include <gtest/gtest.h>
+#include <glib.h>
+
+#include <iostream>
+#include <memory>
+
+class PreferenceUnitTest : public testing::Test {
+ public:
+  virtual void SetUp() {
+    mainloop_ = g_main_loop_new(nullptr, FALSE);
+
+    preference_remove_all();
+  }
+  virtual void TearDown() {
+    preference_remove_all();
+
+    g_main_loop_unref(mainloop_);
+    mainloop_ = nullptr;
+  }
+
+  void RunMainLoop() {
+    g_main_loop_run(mainloop_);
+  }
+
+  void Finish() {
+    g_main_loop_quit(mainloop_);
+  }
+
+  bool touch_preference_changed_cb_ = false;
+  int item_count_ = 0;
+
+ private:
+  GMainLoop* mainloop_;
+};
+
+TEST_F(PreferenceUnitTest, preference_set_int_P) {
+  int ret = preference_set_int("key:int", 10);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_int_N) {
+  int ret = preference_set_int(nullptr, 10);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_int_P) {
+  int ret = preference_set_int("key:int", 20);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  int value = 0;
+  ret = preference_get_int("key:int", &value);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_EQ(value, 20);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_int_N) {
+  int ret = preference_get_int(nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_double_P) {
+  int ret = preference_set_double("key:double", 22.22f);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_double_N) {
+  int ret = preference_set_double(nullptr, 22.22f);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_double_P) {
+  int ret = preference_set_double("key:double", 12.34f);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  double value = 0;
+  ret = preference_get_double("key:double", &value);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_EQ(value, 12.34f);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_double_N) {
+  int ret = preference_get_double(nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_string_P) {
+  int ret = preference_set_string("key:string", "PreferenceUnitTest");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_string_N) {
+  int ret = preference_set_string(nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_string_P) {
+  int ret = preference_set_string("key:string", "PreferenceUnitTest2");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  char* value = nullptr;
+  ret = preference_get_string("key:string", &value);
+  ASSERT_NE(value, nullptr);
+  auto vp = std::unique_ptr<char, decltype(free)*>(value, free);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_STREQ(vp.get(), "PreferenceUnitTest2");
+}
+
+TEST_F(PreferenceUnitTest, preference_get_string_N) {
+  int ret = preference_get_string(nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_boolean_P) {
+  int ret = preference_set_boolean("key:boolean", true);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_boolean_N) {
+  int ret = preference_set_boolean(nullptr, true);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_boolean_P) {
+  int ret = preference_set_boolean("key:boolean", false);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  bool value = true;
+  ret = preference_get_boolean("key:boolean", &value);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_EQ(value, false);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_boolean_N) {
+  int ret = preference_get_boolean(nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_remove_P) {
+  int ret = preference_set_int("key:remove", 100);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_remove("key:remove");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  int value;
+  ret = preference_get_int("key:remove", &value);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NO_KEY);
+}
+
+TEST_F(PreferenceUnitTest, preference_remove_N) {
+  int ret = preference_remove(nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_remove_all_P) {
+  int ret = preference_set_int("key:removeall_int", 100);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_string("key:removeall_string", "RemoveTest");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_remove_all();
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  int intval;
+  ret = preference_get_int("key:removeall_int", &intval);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NO_KEY);
+
+  char* strval;
+  ret = preference_get_string("key:removeall_string", &strval);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NO_KEY);
+}
+
+TEST_F(PreferenceUnitTest, preference_set_changed_cb_P) {
+  int ret = preference_set_int("key:changed", 1);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_changed_cb("key:changed",
+      [](const char* key, void* user_data) {
+        PreferenceUnitTest* p = static_cast<PreferenceUnitTest*>(user_data);
+        p->touch_preference_changed_cb_ = true;
+        p->Finish();
+      }, this);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_int("key:changed", 2);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  RunMainLoop();
+
+  int value = 0;
+  ret = preference_get_int("key:changed", &value);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_EQ(value, 2);
+
+  preference_unset_changed_cb("key:changed");
+}
+
+TEST_F(PreferenceUnitTest, preference_set_changed_cb_N) {
+  int ret = preference_set_changed_cb(nullptr, nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_unset_changed_cb_P) {
+  int ret = preference_set_string("key:changed", "Changed");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_changed_cb("key:changed",
+      [](const char* key, void* user_data) {
+      }, this);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_unset_changed_cb("key:changed");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+}
+
+TEST_F(PreferenceUnitTest, preference_unset_changed_cb_N) {
+  int ret = preference_unset_changed_cb(nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(PreferenceUnitTest, preference_foreach_item_P) {
+  int ret = preference_set_string("key:item1", "item1");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_int("key:item2", 1);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_double("key:item3", 1);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_set_boolean("key:item4", true);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  ret = preference_foreach_item(
+      [](const char* key, void* user_data) {
+        PreferenceUnitTest* p = static_cast<PreferenceUnitTest*>(user_data);
+        p->item_count_++;
+        return true;
+      }, this);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_EQ(this->item_count_, 4);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_type_P) {
+  int ret = preference_set_string("key:str", "val:str");
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+
+  preference_type_e type = PREFERENCE_TYPE_NONE;
+  ret = preference_get_type("key:str", &type);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_NONE);
+  ASSERT_EQ(type, PREFERENCE_TYPE_STRING);
+}
+
+TEST_F(PreferenceUnitTest, preference_get_type_N) {
+  int ret = preference_get_type(nullptr, nullptr);
+  ASSERT_EQ(ret, PREFERENCE_ERROR_INVALID_PARAMETER);
+}