## Service library ##
ADD_SUBDIRECTORY(service_lib)
+## Manager library ##
+ADD_SUBDIRECTORY(manager)
+
## Server daemon ##
ADD_SUBDIRECTORY(server)
--- /dev/null
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef __TIZEN_UIX_AUTOFILL_MANAGER_DOC_H__
+#define __TIZEN_UIX_AUTOFILL_MANAGER_DOC_H__
+
+
+/**
+ * @ingroup CAPI_UIX_AUTOFILL_MODULE
+ * @defgroup CAPI_UIX_AUTOFILL_MANAGER_MODULE Autofill manager
+ * @brief The @ref CAPI_UIX_AUTOFILL_MANAGER_MODULE API provides the functions for getting the current autofill service or changing autofill service.
+ * @section CAPI_UIX_AUTOFILL_MANAGER_MODULE_HEADER Required Header
+ * \#include <autofill_manager.h>
+ *
+ * @section CAPI_UIX_AUTOFILL_MANAGER_MODULE_OVERVIEW Overview
+ * Autofill is a feature that allows you to fill out commonly-entered information such as email, account and address in a text input field. email, account and address in a text input field.
+ * Autofill manager is a module for managing the installed autofill services. Application developers can use this module to get the current autofill service and changing the autofill service.
+ * @ref CAPI_UIX_AUTOFILL_MANAGER_MODULE functions are responsible for sending data for supporting autofill to the autofill service and receiving the commonly-entered data from the autofill service.
+ */
+
+
+#endif /* __TIZEN_UIX_AUTOFILL_MANAGER_DOC_H__ */
*/
#include <tizen.h>
+#include <autofill_error.h>
#ifdef __cplusplus
extern "C" {
*/
/**
- * @brief Enumeration for autofill function error.
- *
- * @since_tizen 5.5
- */
-typedef enum {
- AUTOFILL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
- AUTOFILL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- AUTOFILL_ERROR_NOT_INITIALIZED = TIZEN_ERROR_AUTOFILL | 0x0001, /**< Not initialized */
- AUTOFILL_ERROR_OPERATION_FAILED = TIZEN_ERROR_AUTOFILL | 0x0002, /**< Operation failed */
- AUTOFILL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
-} autofill_error_e;
-
-/**
* @brief Enumeration for autofill hint.
*
* @since_tizen 5.5
--- /dev/null
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef __TIZEN_UIX_AUTOFILL_ERROR_H__
+#define __TIZEN_UIX_AUTOFILL_ERROR_H__
+
+/**
+ * @file autofill_error.h
+ * @brief This file contains autofill error enumeration.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_UIX_AUTOFILL_COMMON_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for autofill function error.
+ *
+ * @since_tizen 5.5
+ */
+typedef enum {
+ AUTOFILL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ AUTOFILL_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ AUTOFILL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+ AUTOFILL_ERROR_NOT_INITIALIZED = TIZEN_ERROR_AUTOFILL | 0x0001, /**< Not initialized */
+ AUTOFILL_ERROR_OPERATION_FAILED = TIZEN_ERROR_AUTOFILL | 0x0002, /**< Operation failed */
+ AUTOFILL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+} autofill_error_e;
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_AUTOFILL_ERROR_H__ */
--- /dev/null
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef __TIZEN_UIX_AUTOFILL_MANAGER_H__
+#define __TIZEN_UIX_AUTOFILL_MANAGER_H__
+
+/**
+ * @file autofill_manager.h
+ * @brief This file contains autofill manager APIs and related enumeration.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <tizen.h>
+#include <autofill_error.h>
+
+/**
+ * @addtogroup CAPI_UIX_AUTOFILL_MANAGER_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration of connection status.
+ * @since_tizen 5.5
+ */
+typedef enum {
+ AUTOFILL_MANAGER_CONNECTION_STATUS_CONNECTED = 0, /**< Connected */
+ AUTOFILL_MANAGER_CONNECTION_STATUS_DISCONNECTED, /**< Disconnected */
+ AUTOFILL_MANAGER_CONNECTION_STATUS_REJECTED, /**< Rejected */
+} autofill_manager_connection_status_e;
+
+/**
+ * @brief The autofill manager handle.
+ * @since_tizen 5.5
+ */
+typedef struct autofill_manager_s *autofill_manager_h;
+
+/**
+ * @brief Called when the connection status is changed.
+ * @since_tizen 5.5
+ * @remarks @a amh should not be freed and can be used only in the callback.
+ * @param[in] amh The autofill manager handle
+ * @param[in] status The connection status
+ * @param[in] user_data The user data passed from the callback function
+ * @see autofill_manager_connect()
+ */
+typedef void (*autofill_manager_connection_status_changed_cb)(autofill_manager_h amh, autofill_manager_connection_status_e status, void* user_data);
+
+/**
+ * @brief Called for each autofill service information.
+ * @since_tizen 5.5
+ * @remarks @a app_id should not be freed and can be used only in the callback.
+ * @param[in] app_id The autofill service app ID
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c true to continue with the next iteration of the loop,
+ * otherwise @c false to break out of the loop
+ * @pre autofill_manager_foreach_autofill_service() will invoke this callback.
+ * @see autofill_manager_foreach_autofill_service()
+ */
+typedef bool (*autofill_manager_autofill_service_cb)(const char *app_id, void *user_data);
+
+/**
+ * @brief Creates a handle for autofill manager.
+ * @since_tizen 5.5
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/autofillmanager
+ * @remarks If the function succeeds, @a amh handle must be released with autofill_manager_destroy().
+ * @param[out] amh The autofill manager handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #AUTOFILL_ERROR_NONE No error
+ * @retval #AUTOFILL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUTOFILL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #AUTOFILL_ERROR_OUT_OF_MEMORY Out of memory
+ * @see autofill_manager_destroy()
+ */
+int autofill_manager_create(autofill_manager_h *amh);
+
+/**
+ * @brief Destroys autofill manager handle.
+ * @since_tizen 5.5
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/autofillmanager
+ * @param[in] amh The autofill manager handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #AUTOFILL_ERROR_NONE No error
+ * @retval #AUTOFILL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUTOFILL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #AUTOFILL_ERROR_NOT_INITIALIZED Not initialized
+ * @see autofill_manager_create()
+ */
+int autofill_manager_destroy(autofill_manager_h amh);
+
+/**
+ * @brief Connects to autofill manager daemon.
+ * @since_tizen 5.5
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/autofillmanager
+ * @param[in] amh The autofill manager handle
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #AUTOFILL_ERROR_NONE No error
+ * @retval #AUTOFILL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUTOFILL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #AUTOFILL_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #AUTOFILL_ERROR_OPERATION_FAILED Operation failure
+ */
+int autofill_manager_connect(autofill_manager_h amh, autofill_manager_connection_status_changed_cb callback, void *user_data);
+
+/**
+ * @platform
+ * @brief Sets autofill service.
+ * @since_tizen 5.5
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/autofillmanager
+ * @param[in] amh The autofill manager handle
+ * @param[in] app_id The autofill service app ID
+ * @return 0 on success, otherwise a negative error value
+ * @retval #AUTOFILL_ERROR_NONE No error
+ * @retval #AUTOFILL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUTOFILL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #AUTOFILL_ERROR_NOT_INITIALIZED Not initialized
+ * @see autofill_manager_get_autofill_service()
+ */
+int autofill_manager_set_autofill_service(autofill_manager_h amh, const char *app_id);
+
+/**
+ * @brief Gets autofill service app ID.
+ * @since_tizen 5.5
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/autofillmanager
+ * @remarks @a service_app_id must be released using free().
+ * @param[in] amh The autofill manager handle
+ * @param[out] service_app_id The autofill service app ID
+ * @return 0 on success, otherwise a negative error value
+ * @retval #AUTOFILL_ERROR_NONE No error
+ * @retval #AUTOFILL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUTOFILL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #AUTOFILL_ERROR_NOT_INITIALIZED Not initialized
+ * @see autofill_manager_set_autofill_service()
+ */
+int autofill_manager_get_autofill_service(autofill_manager_h amh, char **service_app_id);
+
+/**
+ * @brief Retrieves all autofill services.
+ * @since_tizen 5.5
+ * @privlevel platform
+ * @privilege %http://tizen.org/privilege/autofillmanager
+ * @param[in] amh The autofill manager handle
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #AUTOFILL_ERROR_NONE No error
+ * @retval #AUTOFILL_ERROR_PERMISSION_DENIED The application does not have the privilege to call this function
+ * @retval #AUTOFILL_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUTOFILL_ERROR_NOT_INITIALIZED Not initialized
+ * @retval #AUTOFILL_ERROR_OPERATION_FAILED Operation failure
+ */
+int autofill_manager_foreach_autofill_service(autofill_manager_h amh, autofill_manager_autofill_service_cb callback, void* user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_AUTOFILL_MANAGER_H__ */
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(project_prefix "capi")
+SET(prefix "/usr")
+SET(version "0.0.1")
+SET(maintainer "Jihoon Kim <jihoon48.kim@samsung.com>")
+SET(description "Autofill Manager APIs")
+SET(service "ui")
+SET(submodule "autofill-manager")
+SET(dependents "capi-base-common dlog eina glib-2.0 rpc-port cynara-client cynara-session")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+
+SET(Services
+ "application"
+ "base"
+ "content"
+ "location"
+ "media"
+ "messaging"
+ "network"
+ "social"
+ "telephony"
+ "system"
+ "ui"
+ )
+
+#FILE(STRINGS config.cfg configs REGEX "^ *[^#]")
+FOREACH(lines ${configs})
+# MESSAGE(${lines})
+ IF(${lines} MATCHES "([^=]*)=['\"](.*)['\"]")
+ SET(key ${CMAKE_MATCH_1})
+ SET(value ${CMAKE_MATCH_2})
+# MESSAGE("${key} -> ${value}")
+ SET(${key} "${value}")
+ ENDIF()
+ENDFOREACH(lines ${configs})
+
+LIST(FIND Services ${service} sfind)
+
+IF( ${sfind} EQUAL -1 )
+ MESSAGE(FATAL_ERROR "Service must be one of ")
+ FOREACH( s IN ${Services} )
+ MESSAGE(FATAL_ERROR "[${s}]")
+ ENDFOREACH( s IN ${Services} )
+ENDIF( ${sfind} EQUAL -1 )
+
+SET(fw_name "${project_prefix}-${service}-${submodule}")
+
+PROJECT(${fw_name} C)
+
+SET(CMAKE_INSTALL_PREFIX ${prefix})
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(VERSION ${version})
+
+SET(INC_DIR ../include .)
+INCLUDE_DIRECTORIES(${INC_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_name} REQUIRED ${dependents})
+FOREACH(flag ${${fw_name}_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -fpermissive")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
+IF("${ARCH}" STREQUAL "arm")
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
+
+aux_source_directory(. SOURCES)
+aux_source_directory(../privilege_checker PRIV_SOURCES)
+ADD_LIBRARY(${fw_name} SHARED ${SOURCES} ${PRIV_SOURCES})
+
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${fw_name}
+ PROPERTIES
+ VERSION ${FULLVER}
+ SOVERSION ${MAJORVER}
+ CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_name} DESTINATION ${LIBDIR})
+INSTALL(
+ DIRECTORY ${INC_DIR}/ DESTINATION include
+ FILES_MATCHING
+ PATTERN "*_private.h" EXCLUDE
+ PATTERN "${INC_DIR}/*.h"
+ )
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${dependents})
+SET(PC_LDFLAGS -l${fw_name})
+
+CONFIGURE_FILE(
+ capi-ui-autofill-manager.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+ @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIBDIR}/pkgconfig)
--- /dev/null
+/*
+ * Copyright (c) 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 <stdlib.h>
+#include <string.h>
+#include <dlog.h>
+#include <unistd.h>
+#include <autofill_manager.h>
+#include <rpc-port.h>
+#include "autofill_manager_proxy.h"
+#include "../privilege_checker/privilege_checker_private.h"
+
+#define AUTOFILL_DAEMON_APP_ID "org.tizen.autofill-daemon"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AUTOFILL_MANAGER"
+
+struct autofill_manager_s {
+ rpc_port_proxy_AutofillManagerPort_h rpc_h;
+ autofill_manager_connection_status_changed_cb connection_callback;
+ void *connection_userdata;
+};
+
+static void __on_connected(rpc_port_proxy_AutofillManagerPort_h h, void *user_data)
+{
+ autofill_manager_h amh = user_data;
+ LOGI("[__RPC_PORT__] connected");
+
+ if (amh->connection_callback)
+ amh->connection_callback(amh, AUTOFILL_MANAGER_CONNECTION_STATUS_CONNECTED, amh->connection_userdata);
+}
+
+//LCOV_EXCL_START
+static void __on_disconnected(rpc_port_proxy_AutofillManagerPort_h h, void *user_data)
+{
+ autofill_manager_h amh = user_data;
+ LOGD("disconnected");
+
+ if (amh->connection_callback)
+ amh->connection_callback(amh, AUTOFILL_MANAGER_CONNECTION_STATUS_DISCONNECTED, amh->connection_userdata);
+
+ amh->rpc_h = NULL;
+}
+
+static void __on_rejected(rpc_port_proxy_AutofillManagerPort_h h, void *user_data)
+{
+ autofill_manager_h amh = user_data;
+ LOGD("rejected");
+
+ if (amh->connection_callback)
+ amh->connection_callback(amh, AUTOFILL_MANAGER_CONNECTION_STATUS_REJECTED, amh->connection_userdata);
+}
+//LCOV_EXCL_STOP
+
+EXPORT_API int autofill_manager_create(autofill_manager_h *amh)
+{
+ int ret;
+
+ LOGD("autofill manager initialize");
+
+ if (!amh) {
+ LOGW("Invalid paramater");
+ return AUTOFILL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!check_privilege(AUTOFILL_MANAGER_PRIVILEGE)) {
+ LOGW("Permission denied");
+ return AUTOFILL_ERROR_PERMISSION_DENIED;
+ }
+ else {
+ LOGD("Succeed to check privilege");
+ }
+
+ struct autofill_manager_s *ams = (autofill_manager_h)calloc(1, sizeof(struct autofill_manager_s));
+ if (!ams)
+ return AUTOFILL_ERROR_OUT_OF_MEMORY;
+
+ rpc_port_proxy_AutofillManagerPort_callback_s rpc_callback = {
+ .connected = __on_connected,
+ .disconnected = __on_disconnected,
+ .rejected = __on_rejected
+ };
+
+ ret = rpc_port_proxy_AutofillManagerPort_create(AUTOFILL_DAEMON_APP_ID, &rpc_callback, ams, &ams->rpc_h);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ LOGW("Failed to create rpc port. err = %d", ret);
+ free(ams);
+ return AUTOFILL_ERROR_OUT_OF_MEMORY;
+ }
+
+ *amh = (autofill_manager_h)ams;
+
+ return AUTOFILL_ERROR_NONE;
+}
+
+EXPORT_API int autofill_manager_destroy(autofill_manager_h amh)
+{
+ LOGD("autofill manager deinitialize");
+
+ if (!amh) {
+ LOGW("Invalid paramater");
+ return AUTOFILL_ERROR_INVALID_PARAMETER;
+ }
+
+ amh->connection_callback = NULL;
+
+ if (!check_privilege(AUTOFILL_MANAGER_PRIVILEGE)) {
+ LOGW("Permission denied");
+ return AUTOFILL_ERROR_PERMISSION_DENIED;
+ }
+ else {
+ LOGD("Succeed to check privilege");
+ }
+
+ if (amh->rpc_h) {
+ rpc_port_proxy_AutofillManagerPort_destroy(amh->rpc_h);
+ amh->rpc_h = NULL;
+ }
+
+ return AUTOFILL_ERROR_NONE;
+}
+
+EXPORT_API int autofill_manager_connect(autofill_manager_h amh, autofill_manager_connection_status_changed_cb callback, void *user_data)
+{
+ LOGD("autofill manager connect");
+
+ int ret;
+
+ if (!amh || !callback) {
+ LOGW("parameter is NULL\n");
+ return AUTOFILL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!check_privilege(AUTOFILL_MANAGER_PRIVILEGE)) {
+ LOGW("Permission denied");
+ return AUTOFILL_ERROR_PERMISSION_DENIED;
+ }
+
+ if (!amh->rpc_h) {
+ LOGW("rpc handle is NULL");
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+
+ amh->connection_callback = callback;
+ amh->connection_userdata = user_data;
+
+ ret = rpc_port_proxy_AutofillManagerPort_connect(amh->rpc_h);
+ switch (ret) {
+ case RPC_PORT_ERROR_PERMISSION_DENIED:
+ LOGW("permission error");
+ break;
+ }
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ LOGW("Failed to connect rpc port. err = %d", ret);
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+
+ return AUTOFILL_ERROR_NONE;
+}
+
+EXPORT_API int autofill_manager_set_autofill_service(autofill_manager_h amh, const char *app_id)
+{
+ LOGD("autofill manager set autofill service");
+
+ if (!amh || !app_id) {
+ LOGW("parameter is NULL");
+ return AUTOFILL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!check_privilege(AUTOFILL_MANAGER_PRIVILEGE)) {
+ LOGW("Permission denied");
+ return AUTOFILL_ERROR_PERMISSION_DENIED;
+ }
+
+ if (!amh->rpc_h) {
+ LOGW("rpc handle is NULL");
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+
+ bool ret = rpc_port_proxy_AutofillManagerPort_invoke_set_autofill_service(amh->rpc_h, app_id);
+ if (ret == false) {
+ LOGW("Failed to send rpc port. err = %d", ret);
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+ return AUTOFILL_ERROR_NONE;
+}
+
+EXPORT_API int autofill_manager_get_autofill_service(autofill_manager_h amh, char **service_app_id)
+{
+ LOGD("autofill manager get autofill service");
+
+ if (!amh || !service_app_id) {
+ LOGW("parameter is NULL");
+ return AUTOFILL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!check_privilege(AUTOFILL_MANAGER_PRIVILEGE)) {
+ LOGW("Permission denied");
+ return AUTOFILL_ERROR_PERMISSION_DENIED;
+ }
+
+ if (!amh->rpc_h) {
+ LOGW("Not initialized");
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+
+ char *app_id = rpc_port_proxy_AutofillManagerPort_invoke_get_autofill_service(amh->rpc_h);
+ if (app_id) {
+ LOGD("service id : %s", app_id);
+ *service_app_id = strdup(app_id);
+ free(app_id);
+ return AUTOFILL_ERROR_NONE;
+ } else {
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+}
+
+EXPORT_API int autofill_manager_foreach_autofill_service(autofill_manager_h amh, autofill_manager_autofill_service_cb callback, void* user_data)
+{
+ int ret;
+
+ if (!amh || !callback) {
+ LOGW("parameter is NULL");
+ return AUTOFILL_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!check_privilege(AUTOFILL_MANAGER_PRIVILEGE)) {
+ LOGW("Permission denied");
+ return AUTOFILL_ERROR_PERMISSION_DENIED;
+ }
+
+ if (!amh->rpc_h) {
+ LOGW("rpc handle is NULL\n");
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+
+ rpc_port_list_string_h app_id_list;
+ rpc_port_list_string_create(&app_id_list);
+ ret = rpc_port_proxy_AutofillManagerPort_invoke_get_autofill_service_list(amh->rpc_h, &app_id_list);
+ if (ret == false) {
+ LOGW("Failed to send rpc port. err = %d", ret);
+ return AUTOFILL_ERROR_OPERATION_FAILED;
+ }
+ rpc_port_list_string_foreach_list_strings(app_id_list, callback, user_data);
+
+ rpc_port_list_string_destroy(app_id_list);
+
+ return AUTOFILL_ERROR_NONE;
+}
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=@LIBDIR@
+includedir=/usr/include
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
+
BuildRequires: pkgconfig(efl)
BuildRequires: pkgconfig(rpc-port)
BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(cynara-client)
+BuildRequires: pkgconfig(cynara-session)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(capi-appfw-preference)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
Autofill Service Library (Development)
+%package -n capi-ui-autofill-manager
+Summary: Autofill Manager Library
+Group: Graphics & UI Framework/Input
+Requires: %{name} = %{version}-%{release}
+
+%description -n capi-ui-autofill-manager
+Autofill Manager Library
+
+
+%package -n capi-ui-autofill-manager-devel
+Summary: Autofill Manager Library (Development)
+Group: Graphics & UI Framework/Input
+Requires: %{name} = %{version}-%{release}
+
+%description -n capi-ui-autofill-manager-devel
+Autofill Manager Library (Development)
+
+
%package -n org.tizen.autofill-daemon
Summary: Autofill Daemon application
Group: Graphics & UI Framework/Input
mv autofill_service_stub.h ./service_lib/
mv autofill_service_stub.c ./service_lib/
+tidlc -p -l C -i tidl/autofill_manager.tidl -o autofill_manager_proxy
+mv autofill_manager_proxy.h ./manager/
+mv autofill_manager_proxy.c ./manager/
+
+tidlc -s -l C -i tidl/autofill_manager.tidl -o autofill_manager_stub
+mv autofill_manager_stub.h ./server/
+mv autofill_manager_stub.c ./server/
+
+
%build
export CFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror"
%files -n capi-ui-autofill-common-devel
%{_includedir}/autofill_common*.h
+%{_includedir}/autofill_error.h
%{_libdir}/pkgconfig/capi-ui-autofill-common.pc
%{_libdir}/libcapi-ui-autofill-common.so
%{_libdir}/pkgconfig/capi-ui-autofill-service.pc
%{_libdir}/libcapi-ui-autofill-service.so
+%files -n capi-ui-autofill-manager
+%manifest manager/capi-ui-autofill-manager.manifest
+%{_libdir}/libcapi-ui-autofill-manager.so.*
+%license LICENSE
+
+%files -n capi-ui-autofill-manager-devel
+%{_includedir}/autofill_error.h
+%{_includedir}/autofill_manager*.h
+%{_libdir}/pkgconfig/capi-ui-autofill-manager.pc
+%{_libdir}/libcapi-ui-autofill-manager.so
+
%files -n org.tizen.autofill-daemon
%manifest server/org.tizen.autofill-daemon.manifest
%{TZ_SYS_RO_PACKAGES}/org.tizen.autofill-daemon.xml
--- /dev/null
+#include "privilege_checker_private.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlog.h>
+
+#include <cynara-client.h>
+#include <cynara-error.h>
+#include <cynara-creds-socket.h>
+#include <cynara-session.h>
+
+bool
+check_privilege(const char *privilege)
+{
+ cynara *p_cynara = NULL;
+ FILE *fp = NULL;
+ char label_path[1024] = "/proc/self/attr/current";
+ char smack_label[1024] = {'\0', };
+ char uid[10] = {0,};
+
+ return true; //FIXME
+
+ int ret = cynara_initialize(&p_cynara, NULL);
+ if (ret != CYNARA_API_SUCCESS) {
+ return false;
+ }
+
+ if (!p_cynara) {
+ return false;
+ }
+
+ fp = fopen(label_path, "r");
+ if (fp != NULL) {
+ if (fread(smack_label, 1, sizeof(smack_label) - 1, fp) <= 0) {
+ LOGW("[check_privilege] fail to fread");
+ }
+ fclose(fp);
+ }
+
+ pid_t pid = getpid();
+ snprintf(uid, 10, "%d", getuid());
+ char *session = cynara_session_from_pid(pid);
+ ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
+ if (session)
+ free(session);
+
+ if (p_cynara)
+ cynara_finish(p_cynara);
+
+ if (ret != CYNARA_API_ACCESS_ALLOWED) {
+ return false;
+ }
+ return true;
+}
--- /dev/null
+#ifndef __PRIVILEGE_CHECKER_H
+#define __PRIVILEGE_CHECKER_H
+
+#include <stdbool.h>
+
+#define AUTOFILL_MANAGER_PRIVILEGE "http://tizen.org/privilege/autofillmanager"
+
+bool check_privilege(const char *privilege);
+
+#endif /* __PRIVILEGE_CHECKER_H */
SET(SRCS
main.c
+ autofill_config.c
autofill_stub.c
+ autofill_manager_stub.c
autofill_service_proxy.c
)
capi-appfw-service-application
rpc-port
glib-2.0
+ capi-appfw-app-manager
+ capi-appfw-preference
+ eina
)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include)
--- /dev/null
+ /*
+ * Copyright (c) 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 <tizen.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <app_preference.h>
+#include <Eina.h>
+#include <dlog.h>
+
+#include "autofill_config.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "AUTOFILL_DAEMON"
+
+#define SETTING_ACTIVE_AUTOFILL_SERVICE "ActiveAutofillService"
+#define AUTOFILL_SYSTEM_CONFIG_FILE "/etc/autofill/config"
+
+bool autofill_config_get_autofill_service_app_id(char **app_id)
+{
+ char *active_autofill_service_id = NULL;
+ FILE *pFile = NULL;
+ Eina_Strbuf *sb_key = NULL, *sb_value = NULL;
+ const char *key_str = NULL;
+ const char *value_str = NULL;
+ bool ret = false;
+ char strTemp[1024];
+
+ if (preference_get_string(SETTING_ACTIVE_AUTOFILL_SERVICE, &active_autofill_service_id) == PREFERENCE_ERROR_NONE) {
+ LOGD("preference active autofill service : %s", active_autofill_service_id);
+ *app_id = active_autofill_service_id;
+ return true;
+ }
+
+ LOGD("Read from config");
+
+ pFile = fopen(AUTOFILL_SYSTEM_CONFIG_FILE, "r");
+ if (pFile == NULL)
+ return false;
+
+ while (fgets(strTemp, sizeof(strTemp), pFile) != NULL)
+ {
+ char **result_arr = eina_str_split(strTemp, "=", 0);
+ if (!result_arr)
+ continue;
+
+ if (!result_arr[0]) {
+ free(result_arr);
+ continue;
+ }
+
+ sb_key = eina_strbuf_new();
+ eina_strbuf_append(sb_key, result_arr[0]);
+ eina_strbuf_trim(sb_key);
+
+ key_str = eina_strbuf_string_get(sb_key);
+ if (key_str) {
+ if (strcmp(key_str, SETTING_ACTIVE_AUTOFILL_SERVICE) == 0) {
+ if (result_arr[1]) {
+ sb_value = eina_strbuf_new();
+ eina_strbuf_append(sb_value, result_arr[1]);
+ eina_strbuf_trim(sb_value);
+ value_str = eina_strbuf_string_get(sb_value);
+
+ if (app_id && value_str) {
+ *app_id = strdup(value_str);
+ ret = true;
+ }
+
+ eina_strbuf_free(sb_value);
+ }
+ }
+ eina_strbuf_free(sb_key);
+ }
+
+ /* Free the memory */
+ free(result_arr[0]);
+ free(result_arr);
+
+ if (ret)
+ break;
+ } /* end of while */
+
+ fclose(pFile);
+
+ return ret;
+}
+
+bool autofill_config_set_autofill_service_app_id(const char *app_id)
+{
+ if (preference_set_string(SETTING_ACTIVE_AUTOFILL_SERVICE, app_id) == PREFERENCE_ERROR_NONE)
+ return true;
+
+ return false;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 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.
+ */
+
+#ifndef __AUTOFILL_CONFIG_H__
+#define __AUTOFILL_CONFIG_H__
+
+#include <stdbool.h>
+
+#define AUTOFILL_SERVICE_APP_ID "org.tizen.autofill-service"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool autofill_config_get_autofill_service_app_id(char **app_id);
+bool autofill_config_set_autofill_service_app_id(const char *app_id);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AUTOFILL_CONFIG_H__ */
#include <dlog.h>
#include <glib.h>
#include <rpc-port.h>
+#include <app_manager.h>
#include "autofill_stub.h"
#include "autofill_service_proxy.h"
+#include "autofill_manager_stub.h"
+#include "autofill_config.h"
#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "AUTOFILL_DAEMON"
-#define AUTOFILL_SERVICE_APP_ID "org.tizen.autofill-service"
static rpc_port_proxy_AutofillSvcPort_h rpc_h = NULL;
+static int connect_service();
+
typedef struct {
char *app_id;
continue;
}
- if (strcmp(client->app_id, app_id) == 0) {
+ if (client->app_id && strcmp(client->app_id, app_id) == 0) {
return client;
}
}
if (!handle)
return;
- if (handle->auth_info_cb)
+ if (handle->auth_info_cb) {
rpc_port_AutofillAppPort_autofill_auth_info_received_cb_destroy(handle->auth_info_cb);
+ handle->auth_info_cb = NULL;
+ }
- if (handle->fill_response_received_cb)
+ if (handle->fill_response_received_cb) {
rpc_port_AutofillAppPort_autofill_fill_response_received_cb_destroy(handle->fill_response_received_cb);
+ handle->fill_response_received_cb = NULL;
+ }
- if (handle->app_id)
+ if (handle->app_id) {
free(handle->app_id);
+ handle->app_id = NULL;
+ }
free(handle);
}
__remove_client(context);
}
+static void __manager_create(rpc_port_stub_AutofillManagerPort_context_h context,
+ void *user_data)
+{
+ LOGD("");
+}
+
+static void __manager_terminate(rpc_port_stub_AutofillManagerPort_context_h context,
+ void *user_data)
+{
+ LOGD("");
+}
+
bool __view_info_item_cb(rpc_port_autofill_item_h items, void *user_data)
{
char *id = NULL;
char *sender = NULL;
autofill_client_s *sender_client;
+ if (!rpc_h) {
+ LOGW("Not initialized");
+ return -1;
+ }
+
rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
char *view_id = NULL;
char *sender = NULL;
char *view_id = NULL;
+ if (!rpc_h) {
+ LOGW("Not initialized");
+ return -1;
+ }
+
rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
rpc_port_autofill_view_info_get_view_id(vi, &view_id);
char *sender = NULL;
autofill_client_s *sender_client;
+ if (!rpc_h) {
+ LOGW("Not initialized");
+ return -1;
+ }
+
rpc_port_stub_AutofillAppPort_context_get_sender(context, &sender);
if (sender) {
LOGD("sender(%s)", sender);
}
//LCOV_EXCL_STOP
+static bool __manager_set_autofill_service_cb(rpc_port_stub_AutofillManagerPort_context_h context, const char *app_id, void *user_data)
+{
+ LOGD("app id : %s", app_id);
+
+ if (app_id)
+ autofill_config_set_autofill_service_app_id(app_id);
+
+ if (rpc_h) {
+ LOGD("send terminate");
+ // terminate service
+ rpc_port_proxy_AutofillSvcPort_invoke_request_terminate(rpc_h);
+
+ int ret = rpc_port_proxy_AutofillSvcPort_destroy(rpc_h);
+ LOGD("ret : %d", ret);
+ }
+
+ rpc_h = NULL;
+
+ connect_service();
+
+ return true;
+}
+
+static char * __manager_get_autofill_service_cb(rpc_port_stub_AutofillManagerPort_context_h context, void *user_data)
+{
+ if (!rpc_h) {
+ LOGW("Not initialized");
+ return false;
+ }
+
+ char *app_id;
+ autofill_config_get_autofill_service_app_id(&app_id);
+
+ LOGD("app id : %s", app_id);
+
+ return app_id;
+}
+
+bool add_autofill_service_cb(app_info_h app_info, void *user_data)
+{
+ char *app_id = NULL;
+ rpc_port_list_string_h service_info_list = (rpc_port_list_string_h)user_data;
+
+ int ret = app_info_get_app_id(app_info, &app_id);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ LOGW("app_info_get_app_id failed (%d)", ret);
+ return true;
+ }
+
+ LOGD("Find autofill service : %s", app_id);
+
+ rpc_port_list_string_add_list_strings(service_info_list, app_id);
+
+ if (app_id) {
+ free(app_id);
+ }
+
+ return true;
+}
+
+static bool __manager_get_autofill_service_list_cb(rpc_port_stub_AutofillManagerPort_context_h context, rpc_port_list_string_h *service_info_list, void *user_data)
+{
+ int ret;
+ app_info_metadata_filter_h handle = NULL;
+
+ // Get the Autofill service list
+ ret = app_info_metadata_filter_create(&handle);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ LOGW("app_info_metadata_filter_create failed (%d)", ret);
+ app_info_metadata_filter_destroy(handle);
+ return false;
+ }
+
+ ret = app_info_metadata_filter_add(handle, "autofill-service", "true");
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ LOGW("app_info_metadata_filter_add failed (%d)", ret);
+ app_info_metadata_filter_destroy(handle);
+ return false;
+ }
+
+ rpc_port_list_string_h app_id_list_h;
+ rpc_port_list_string_create(&app_id_list_h);
+
+ ret = app_info_metadata_filter_foreach(handle, add_autofill_service_cb, app_id_list_h);
+ if (ret != APP_MANAGER_ERROR_NONE) {
+ LOGW("app_info_metadata_filter_foreach failed (%d)", ret);
+ }
+
+ *service_info_list = app_id_list_h;
+
+ app_info_metadata_filter_destroy(handle);
+
+ return true;
+}
+
static int connect_service()
{
int ret;
+ size_t service_id_len;
rpc_port_proxy_AutofillSvcPort_callback_s rpc_callback = {
.connected = __on_connected,
return RPC_PORT_ERROR_NONE;
}
- ret = rpc_port_proxy_AutofillSvcPort_create(AUTOFILL_SERVICE_APP_ID, &rpc_callback, NULL, &rpc_h);
- if (ret != RPC_PORT_ERROR_NONE) {
- LOGW("Failed to create rpc port. err = %d", ret);
- return false;
+ char *active_autofill_service_id = NULL;
+ autofill_config_get_autofill_service_app_id(&active_autofill_service_id);
+ LOGD("autofill service : '%s'", active_autofill_service_id);
+
+ if (!active_autofill_service_id) {
+ active_autofill_service_id = strdup(AUTOFILL_SERVICE_APP_ID);
+ }
+
+ if (active_autofill_service_id) {
+ autofill_config_set_autofill_service_app_id(active_autofill_service_id);
+ service_id_len = strlen(active_autofill_service_id);
+
+ if (service_id_len > 0) {
+ ret = rpc_port_proxy_AutofillSvcPort_create(active_autofill_service_id, &rpc_callback, NULL, &rpc_h);
+ }
+ free(active_autofill_service_id);
+
+ if (service_id_len == 0) {
+ LOGD("No Autofill service to connect");
+ return false;
+ }
+
+ if (ret != RPC_PORT_ERROR_NONE) {
+ LOGW("Failed to create rpc port. err = %d", ret);
+ return false;
+ }
}
ret = rpc_port_proxy_AutofillSvcPort_connect(rpc_h);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ LOGW("Failed to connect. err = %d", ret);
+ return false;
+ }
return ret;
}
LOGD("");
int ret;
+ // register app port
rpc_port_stub_AutofillAppPort_callback_s callback = {
__message_create,
__message_terminate,
ret = rpc_port_stub_AutofillAppPort_register(&callback, NULL);
if (ret != 0)
- LOGI("Failed to register message");
+ LOGI("Failed to register app port");
+ else
+ LOGI("Succeeded to register app port");
+
+ // register manager port
+ rpc_port_stub_AutofillManagerPort_callback_s manager_callback = {
+ __manager_create,
+ __manager_terminate,
+ __manager_set_autofill_service_cb,
+ __manager_get_autofill_service_cb,
+ __manager_get_autofill_service_list_cb,
+ };
+
+ ret = rpc_port_stub_AutofillManagerPort_register(&manager_callback, NULL);
+ if (ret != 0)
+ LOGI("Failed to register manager port");
else
- LOGI("Succeeded to register message");
+ LOGI("Succeeded to register manager port");
connect_service();
--- /dev/null
+interface AutofillManagerPort {
+ bool set_autofill_service(string app_id);
+ string get_autofill_service();
+ bool get_autofill_service_list(out list<string> service_info_list);
+}