From 8a238ff2cf08fb5bc2c7813eae61d91da4fa1d4b Mon Sep 17 00:00:00 2001
From: Piotr Sawicki
Date: Thu, 22 Jun 2017 13:53:56 +0200
Subject: [PATCH] Add a skeleton of client API implementation
Change-Id: I067a35ae6b712c7f67076e30a29efdbf0ced6d79
---
CMakeLists.txt | 7 +-
packaging/askuser-notification.spec | 32 ++
pkgconfig/CMakeLists.txt | 20 +
.../askuser-notification-client/CMakeLists.txt | 26 ++
.../askuser-notification-client.pc.in | 14 +
src/client/CMakeLists.txt | 68 +++
src/client/api/ApiInterface.h | 51 ++
src/client/api/askuser-notification-client.cpp | 127 +++++
src/client/impl/ApiInterfaceImpl.cpp | 68 +++
src/client/impl/ApiInterfaceImpl.h | 56 +++
src/client/impl/PopupCallbackClosure.h | 52 +++
src/client/impl/StatusCallbackClosure.h | 52 +++
src/client/include/askuser-notification-client.h | 519 +++++++++++++++++++++
13 files changed, 1091 insertions(+), 1 deletion(-)
create mode 100644 pkgconfig/CMakeLists.txt
create mode 100644 pkgconfig/askuser-notification-client/CMakeLists.txt
create mode 100644 pkgconfig/askuser-notification-client/askuser-notification-client.pc.in
create mode 100644 src/client/CMakeLists.txt
create mode 100644 src/client/api/ApiInterface.h
create mode 100644 src/client/api/askuser-notification-client.cpp
create mode 100644 src/client/impl/ApiInterfaceImpl.cpp
create mode 100644 src/client/impl/ApiInterfaceImpl.h
create mode 100644 src/client/impl/PopupCallbackClosure.h
create mode 100644 src/client/impl/StatusCallbackClosure.h
create mode 100644 src/client/include/askuser-notification-client.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 76ba1e0..d70618b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,8 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
PROJECT("askuser")
-SET(ASKUSER_VERSION 0.1.0)
+SET(ASKUSER_VERSION_MAJOR 0)
+SET(ASKUSER_VERSION ${ASKUSER_VERSION_MAJOR}.1.13)
############################# cmake packages ##################################
@@ -82,11 +83,15 @@ SET(TARGET_ASKUSER_NOTIFICATION "askuser-notification")
SET(TARGET_ASKUSER_COMMON "askuser-notification-common")
SET(TARGET_ASKUSER_NOTIFICATION_LIB "askuser-notification-ipc")
SET(TARGET_ASKUSER_NOTIFICATION_TEST "askuser-notification-test")
+SET(TARGET_ASKUSER_NOTIFICATION_CLIENT_LIB "askuser-notification-client")
SET(TARGET_PLUGIN_SERVICE "askuser-plugin-service")
ADD_SUBDIRECTORY(src/plugin)
ADD_SUBDIRECTORY(src/notification-daemon)
ADD_SUBDIRECTORY(src/common)
ADD_SUBDIRECTORY(src/common/protocol)
+ADD_SUBDIRECTORY(src/client)
+
+ADD_SUBDIRECTORY(pkgconfig)
IF (BUILD_WITH_SYSTEMD_DAEMON)
ADD_SUBDIRECTORY(systemd)
diff --git a/packaging/askuser-notification.spec b/packaging/askuser-notification.spec
index e7dd07e..9365a20 100644
--- a/packaging/askuser-notification.spec
+++ b/packaging/askuser-notification.spec
@@ -67,6 +67,24 @@ Summary: Tool for testing askuser-notification
%description test
Tool for testing askuser-notification
+%package client
+Summary: Askuser notification client library
+Requires: askuser-notification-libs
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description client
+Askuser notification client library allows to check if an application
+has a particular privilege. It also allows an application to determine privacy
+privileges. It communicates with the askuser-notification service. It is an
+asynchronous API, therefore it can be integrated with any event loop mechanism.
+
+%package client-devel
+Summary: Askuser notification client library development files
+
+%description client-devel
+Askuser notification client library development files
+
%prep
%setup -q
cp -a %{SOURCE1001} .
@@ -123,6 +141,10 @@ systemctl restart cynara.service
%postun libs -p /sbin/ldconfig
+%post client -p /sbin/ldconfig
+
+%postun client -p /sbin/ldconfig
+
%files -f %{name}.lang
%manifest default.manifest
%license LICENSE
@@ -156,3 +178,13 @@ systemctl restart cynara.service
%files test
%attr(755,root,root) %{_bindir}/askuser-notification-test
+
+%files client
+%manifest default.manifest
+%license LICENSE
+%attr(644,-,-) %{_libdir}/libaskuser-notification-client.so.*
+
+%files client-devel
+%{_includedir}/askuser-notification-client/*.h
+%{_libdir}/pkgconfig/askuser-notification-client.pc
+%{_libdir}/libaskuser-notification-client.so
diff --git a/pkgconfig/CMakeLists.txt b/pkgconfig/CMakeLists.txt
new file mode 100644
index 0000000..896e409
--- /dev/null
+++ b/pkgconfig/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (c) 2017 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.
+#
+# @file CMakeLists.txt
+# @author Piotr Sawicki
+#
+
+ADD_SUBDIRECTORY(askuser-notification-client)
+
diff --git a/pkgconfig/askuser-notification-client/CMakeLists.txt b/pkgconfig/askuser-notification-client/CMakeLists.txt
new file mode 100644
index 0000000..491f95d
--- /dev/null
+++ b/pkgconfig/askuser-notification-client/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright (c) 2017 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.
+#
+# @file CMakeLists.txt
+# @author Piotr Sawicki
+#
+
+CONFIGURE_FILE(askuser-notification-client.pc.in askuser-notification-client.pc @ONLY)
+
+INSTALL(FILES
+ ${CMAKE_BINARY_DIR}/pkgconfig/askuser-notification-client/askuser-notification-client.pc
+ DESTINATION
+ ${LIB_INSTALL_DIR}/pkgconfig
+ )
+
diff --git a/pkgconfig/askuser-notification-client/askuser-notification-client.pc.in b/pkgconfig/askuser-notification-client/askuser-notification-client.pc.in
new file mode 100644
index 0000000..46bd583
--- /dev/null
+++ b/pkgconfig/askuser-notification-client/askuser-notification-client.pc.in
@@ -0,0 +1,14 @@
+# Package Information for pkg-config
+
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: askuser-notification-client
+Description: askuser-notification-client library
+Version: @ASKUSER_VERSION@
+Requires:
+Libs: -L${libdir} -laskuser-notification-client
+Cflags: -I${includedir}/askuser-notification-client
+
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
new file mode 100644
index 0000000..09c9049
--- /dev/null
+++ b/src/client/CMakeLists.txt
@@ -0,0 +1,68 @@
+
+# Copyright (c) 2017 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.
+#
+# @file CMakeLists.txt
+# @author Piotr Sawicki
+#
+
+SET(ASKUSER_NOTIFICATION_CLIENT_PATH ${ASKUSER_PATH}/client)
+
+PKG_CHECK_MODULES(ASKUSER_NOTIFICATION_CLIENT_DEP
+ REQUIRED
+ )
+
+INCLUDE_DIRECTORIES(SYSTEM ${ASKUSER_NOTIFICATION_CLIENT_DEP_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(
+ ${ASKUSER_NOTIFICATION_CLIENT_PATH}/api
+ ${ASKUSER_NOTIFICATION_CLIENT_PATH}/impl
+ ${ASKUSER_NOTIFICATION_CLIENT_PATH}/include
+ )
+
+SET(ASKUSER_NOTIFICATION_CLIENT_SOURCES
+ ${ASKUSER_NOTIFICATION_CLIENT_PATH}/api/askuser-notification-client.cpp
+ ${ASKUSER_NOTIFICATION_CLIENT_PATH}/impl/ApiInterfaceImpl.cpp
+ )
+
+ADD_DEFINITIONS("-fvisibility=default")
+
+ADD_LIBRARY(
+ ${TARGET_ASKUSER_NOTIFICATION_CLIENT_LIB}
+ SHARED
+ ${ASKUSER_NOTIFICATION_CLIENT_SOURCES}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_ASKUSER_NOTIFICATION_CLIENT_LIB}
+ PROPERTIES
+ SOVERSION ${ASKUSER_VERSION_MAJOR}
+ VERSION ${ASKUSER_VERSION}
+ OUTPUT_NAME "askuser-notification-client"
+ )
+
+LINK_DIRECTORIES(${ASKUSER_NOTIFICATION_CLIENT_DEP_LIBRARY_DIRS})
+
+TARGET_LINK_LIBRARIES(
+ ${TARGET_ASKUSER_NOTIFICATION_CLIENT_LIB}
+ ${TARGET_ASKUSER_NOTIFICATION_LIB}
+ ${TARGET_ASKUSER_COMMON}
+ ${ASKUSER_NOTIFICATION_CLIENT_DEP_LIBRARIES}
+)
+
+INSTALL(TARGETS ${TARGET_ASKUSER_NOTIFICATION_CLIENT_LIB}
+ DESTINATION ${LIB_INSTALL_DIR})
+
+FILE(GLOB HEADERS ${ASKUSER_NOTIFICATION_CLIENT_PATH}/include/*.h)
+INSTALL(FILES ${HEADERS}
+ DESTINATION ${INCLUDE_INSTALL_DIR}/askuser-notification-client)
+
diff --git a/src/client/api/ApiInterface.h b/src/client/api/ApiInterface.h
new file mode 100644
index 0000000..8c3ab54
--- /dev/null
+++ b/src/client/api/ApiInterface.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 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
+ */
+
+/**
+ * @file ApiInterface.h
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief This file contains the declaration of ApiInterface.
+ */
+
+#pragma once
+
+#include
+
+#include
+#include
+
+namespace AskUser {
+
+namespace Client {
+
+using RequestId = int;
+
+class ApiInterface
+{
+public:
+ virtual ~ApiInterface() {}
+
+ virtual int process(int fd, int events) = 0;
+ virtual askuser_check_result checkPrivilege(const std::string &privilege) = 0;
+ virtual RequestId popupRequest(const PopupCallbackClosure &closure,
+ const std::string &privilege) = 0;
+};
+
+} // namespace Client
+
+} // namespace AskUser
+
diff --git a/src/client/api/askuser-notification-client.cpp b/src/client/api/askuser-notification-client.cpp
new file mode 100644
index 0000000..803088b
--- /dev/null
+++ b/src/client/api/askuser-notification-client.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2017 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
+ */
+/**
+ * @file askuser-notification-client.cpp
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief This file contains the implementation of the askuser-notification client API.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+struct askuser_client {
+ AskUser::Client::ApiInterface *impl;
+
+ askuser_client(AskUser::Client::ApiInterface *_impl) : impl(_impl) {
+ }
+
+ ~askuser_client() {
+ delete impl;
+ }
+};
+
+int askuser_client_initialize(askuser_client **pp_client,
+ askuser_status_callback status_callback, void *p_user_data)
+{
+ if (!pp_client)
+ return ASKUSER_API_INVALID_PARAM;
+
+ try {
+ AskUser::Client::StatusCallbackClosure closure(status_callback, p_user_data);
+
+ std::unique_ptr ptr;
+ ptr.reset(new AskUser::Client::ApiInterfaceImpl(closure));
+
+ *pp_client = new askuser_client(ptr.get());
+
+ ptr.release();
+ } catch (...) {
+ // TODO handle exceptions
+ return ASKUSER_API_UNKNOWN_ERROR;
+ }
+
+ return ASKUSER_API_SUCCESS;
+}
+
+void askuser_client_finalize(askuser_client *p_client)
+{
+ if (!p_client)
+ return;
+
+ try {
+ delete p_client;
+ } catch (...) {
+ // TODO
+ }
+}
+
+int askuser_client_process(askuser_client *p_client, int fd, int events)
+{
+ if (!p_client)
+ return ASKUSER_API_INVALID_PARAM;
+
+ try {
+ return p_client->impl->process(fd, events);
+ } catch (...) {
+ // TODO
+ return ASKUSER_API_UNKNOWN_ERROR;
+ }
+}
+
+int askuser_client_check_privilege(askuser_client *p_client,
+ const char *privilege, askuser_check_result *p_result)
+{
+ if (!p_client || !privilege || !p_result)
+ return ASKUSER_API_INVALID_PARAM;
+
+ try {
+ *p_result = p_client->impl->checkPrivilege(privilege);
+ } catch(...) {
+ // TODO handle exceptions
+ return ASKUSER_API_UNKNOWN_ERROR;
+ }
+
+ return ASKUSER_API_SUCCESS;
+}
+
+int askuser_client_popup_request(askuser_client *p_client, const char *privilege,
+ askuser_popup_response_callback response_callback,
+ void *p_user_data, int *p_request_id)
+{
+ if (!p_client || !response_callback || !privilege)
+ return ASKUSER_API_INVALID_PARAM;
+
+ try {
+ AskUser::Client::PopupCallbackClosure closure(response_callback, p_user_data);
+ AskUser::Client::RequestId id = p_client->impl->popupRequest(closure, privilege);
+
+ if (p_request_id != nullptr) {
+ *p_request_id = id;
+ }
+ } catch (...) {
+ // TODO handle exceptions
+ return ASKUSER_API_UNKNOWN_ERROR;
+ }
+
+ return ASKUSER_API_SUCCESS;
+}
diff --git a/src/client/impl/ApiInterfaceImpl.cpp b/src/client/impl/ApiInterfaceImpl.cpp
new file mode 100644
index 0000000..ce90206
--- /dev/null
+++ b/src/client/impl/ApiInterfaceImpl.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 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
+ */
+
+/**
+ * @file ApiInterfaceImpl.cpp
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief The definition of ApiInterfaceImpl.
+ */
+
+#include "ApiInterfaceImpl.h"
+
+namespace AskUser {
+
+namespace Client {
+
+ApiInterfaceImpl::ApiInterfaceImpl(const StatusCallbackClosure &statusClosure)
+: m_statusClosure(statusClosure)
+{
+}
+
+ApiInterfaceImpl::~ApiInterfaceImpl()
+{
+ // TODO
+}
+
+int ApiInterfaceImpl::process(int fd, int events)
+{
+ // TODO
+ (void) fd;
+ (void) events;
+ return 0;
+}
+
+askuser_check_result ApiInterfaceImpl::checkPrivilege(const std::string &privilege)
+{
+ // TODO
+ (void) privilege;
+
+ return ASKUSER_CHECK_RESULT_DENY;
+}
+
+RequestId ApiInterfaceImpl::popupRequest(const PopupCallbackClosure &closure,
+ const std::string &privilege)
+{
+ // TODO
+ (void) closure;
+ (void) privilege;
+
+ return 0;
+}
+
+} // namespace Client
+
+} // namespace AskUser
diff --git a/src/client/impl/ApiInterfaceImpl.h b/src/client/impl/ApiInterfaceImpl.h
new file mode 100644
index 0000000..e255ac2
--- /dev/null
+++ b/src/client/impl/ApiInterfaceImpl.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 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
+ */
+
+/**
+ * @file ApiInterfaceImpl.h
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief The declaration of ApiInterfaceImpl.
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+#include
+
+namespace AskUser {
+
+namespace Client {
+
+class ApiInterfaceImpl : public AskUser::Client::ApiInterface {
+public:
+ ApiInterfaceImpl(const AskUser::Client::StatusCallbackClosure &closure);
+ ApiInterfaceImpl(const ApiInterfaceImpl& orig) = delete;
+ virtual ~ApiInterfaceImpl();
+
+ ApiInterface &operator=(const ApiInterfaceImpl& orig) = delete;
+
+ virtual int process(int fd, int events);
+ virtual askuser_check_result checkPrivilege(const std::string &privilege);
+ virtual RequestId popupRequest(const AskUser::Client::PopupCallbackClosure &closure,
+ const std::string &privilege);
+
+private:
+ AskUser::Client::StatusCallbackClosure m_statusClosure;
+};
+
+} // namespace Client
+
+} // namespace AskUser
+
diff --git a/src/client/impl/PopupCallbackClosure.h b/src/client/impl/PopupCallbackClosure.h
new file mode 100644
index 0000000..ebdf0ee
--- /dev/null
+++ b/src/client/impl/PopupCallbackClosure.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 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
+ */
+
+/**
+ * @file PopupCallbackClosure.h
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief The definition of PopupCallbackClosure.
+ */
+
+#pragma once
+
+#include
+
+namespace AskUser {
+
+namespace Client {
+
+class PopupCallbackClosure {
+public:
+ PopupCallbackClosure(askuser_popup_response_callback callback, void *userData)
+ : m_callback(callback)
+ , m_userData(userData)
+ {}
+
+ void operator()(int requestId, askuser_call_cause cause, askuser_popup_result result) const
+ {
+ m_callback(requestId, cause, result, m_userData);
+ }
+
+private:
+ askuser_popup_response_callback m_callback;
+ void *m_userData;
+};
+
+} // namespace Client
+
+} // namespace AskUser
+
diff --git a/src/client/impl/StatusCallbackClosure.h b/src/client/impl/StatusCallbackClosure.h
new file mode 100644
index 0000000..8a51189
--- /dev/null
+++ b/src/client/impl/StatusCallbackClosure.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 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
+ */
+
+/**
+ * @file StatusCallbackClosure.h
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief The definition of StatusCallbackClosure.
+ */
+
+#pragma once
+
+#include
+
+namespace AskUser {
+
+namespace Client {
+
+class StatusCallbackClosure {
+public:
+ StatusCallbackClosure(askuser_status_callback callback, void *userData)
+ : m_callback(callback)
+ , m_userData(userData)
+ {}
+
+ void operator()(int fd, int events) const
+ {
+ m_callback(fd, events, m_userData);
+ }
+
+private:
+ askuser_status_callback m_callback;
+ void *m_userData;
+};
+
+} // namespace Client
+
+} // namespace AskUser
+
diff --git a/src/client/include/askuser-notification-client.h b/src/client/include/askuser-notification-client.h
new file mode 100644
index 0000000..c1b6df7
--- /dev/null
+++ b/src/client/include/askuser-notification-client.h
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2017 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
+ */
+/**
+ * @file askuser-notification-client.h
+ * @author Piotr Sawicki
+ * @version 1.0
+ * @brief The declaration of the askuser-notification client API.
+ */
+
+#ifndef ASKUSER_NOTIFICATION_CLIENT_H
+#define ASKUSER_NOTIFICATION_CLIENT_H
+
+/**
+ * \name Status return codes
+ * @{
+ */
+
+/*! \brief indicating that the call was successful */
+#define ASKUSER_API_SUCCESS 0
+
+/*! \brief indicating that an unknown error occurred */
+#define ASKUSER_API_UNKNOWN_ERROR -1
+
+/*! \brief indicating that a memory allocation failed */
+#define ASKUSER_API_OUT_OF_MEMORY -2
+
+/*! \brief indicating that an invalid parameter was passed */
+#define ASKUSER_API_INVALID_PARAM -3
+
+/*! \brief indicating that a connection error occurred */
+#define ASKUSER_API_CONNECTION_ERROR -4
+
+/** @} */
+
+/**
+ * \name Types of file descriptor events
+ *
+ * @{
+ */
+
+/*! \brief a file descriptor is ready to read */
+#define ASKUSER_READ_EVENT (1 << 0)
+
+/*! \brief a file descriptor is ready to write */
+#define ASKUSER_WRITE_EVENT (1 << 1)
+
+/*! \brief an error has been detected on a file descriptor by an event loop or
+ * the API wants to inform that a file descriptor is to be closed
+ */
+#define ASKUSER_EMPTY_EVENTS 0
+
+/** @} */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct askuser_client askuser_client;
+
+/**
+ * \enum askuser_check_result
+ * Values indicating the result of an askuser_client_check_privilege() call.
+ *
+ * \var askuser_check_result::ASKUSER_CHECK_RESULT_ALLOW
+ * An application has a privilege.
+ *
+ * \var askuser_check_result::ASKUSER_CHECK_RESULT_DENY
+ * An application does not have a privilege.
+ *
+ * \var askuser_check_result::ASKUSER_CHECK_RESULT_ASK
+ * A user should be asked about whether grant privilege to an application or not.
+ */
+typedef enum {
+ ASKUSER_CHECK_RESULT_ALLOW,
+ ASKUSER_CHECK_RESULT_DENY,
+ ASKUSER_CHECK_RESULT_ASK,
+} askuser_check_result;
+
+/**
+ * \enum askuser_popup_result
+ * Values returned by popup.
+ *
+ * \var askuser_popup_result::ASKUSER_POPUP_RESULT_ALLOW_FOREVER
+ * A user granted a privilege to an application.
+ *
+ * \var askuser_popup_result::ASKUSER_POPUP_RESULT_DENY_FOREVER
+ * A user did not grant a privilege to an application.
+ *
+ * \var askuser_popup_result::ASKUSER_POPUP_RESULT_DENY_ONCE
+ * A user did not grant a privilege to an application for this
+ * particular query.
+ */
+typedef enum {
+ ASKUSER_POPUP_RESULT_ALLOW_FOREVER,
+ ASKUSER_POPUP_RESULT_DENY_FOREVER,
+ ASKUSER_POPUP_RESULT_DENY_ONCE,
+} askuser_popup_result;
+
+/**
+ * \enum askuser_call_cause
+ * Values indicating the reason passed to askuser_popup_response_callback.
+ *
+ * \var askuser_call_cause::ASKUSER_CALL_CAUSE_ANSWER
+ * Callback was called with a valid answer.
+ *
+ * \var askuser_call_cause::ASKUSER_CALL_CAUSE_ERROR
+ * Callback was called because of an error.
+ *
+ * \var askuser_call_cause::ASKUSER_CALL_CAUSE_FINALIZE
+ * Callback was called because askuser_client_finalize() had been called.
+ */
+typedef enum {
+ ASKUSER_CALL_CAUSE_ANSWER,
+ ASKUSER_CALL_CAUSE_ERROR,
+ ASKUSER_CALL_CAUSE_FINALIZE,
+} askuser_call_cause;
+
+
+/**
+ * \brief This callback function is called when the status of a file descriptor changes.
+ *
+ * A file descriptor changes when a client:
+ * - is ready to send a request (after calling: askuser_client_popup_request())
+ * - is ready to receive a response
+ *
+ * This function is crucial to implement an asynchronous API. An application should
+ * register its askuser_status_callback function to monitor file descriptors.
+ * In the body of this callback function, the application should configure its
+ * I/O multiplexing mechanism (select, poll, GLib main loop etc.) to wait for specified
+ * events (events parameter) which may occur on a file descriptor (fd parameter).
+ *
+ * \attention This callback is called from the askuser_client_process() function context.
+ *
+ * \attention The events and fd parameters passed in this callback should be
+ * stored on the application side. Application should use this stored information
+ * in every event loop cycle to configure its I/O multiplexing mechanism.
+ * It is due to the fact that the callback may not be called in every loop cycle for every
+ * askuser_client_process() call. For example, if the API wants to send some data,
+ * it calls the callback with the 'events' param having the ASKUSER_WRITE_EVENT flag set.
+ * Then, askuser_client_process() may be called multiple times until the data is sent.
+ * When this task is done, the callback is called with cleared ASKUSER_WRITE_EVENT,
+ * which means that the application should stop waiting for the WRITE event.
+ *
+ * Have a look at the below simplified code (managing of fd is ommited for better
+ * readability).
+ *
+ * \code
+ * int app_events_to_wait_for;
+ *
+ * void callback(int fd, int events, void *p_user_data)
+ * {
+ * app_events_to_wait_for = events;
+ * }
+ *
+ * void event_loop()
+ * {
+ * for (;;) {
+ * detected_events = wait_for_events(app_events_to_wait_for);
+ * askuser_client_process(client, fd, detected_events);
+ * }
+ * }
+ * \endcode
+ *
+ * \param[in] fd A file descriptor.
+ * \param[in] events It is a bit-field value compounds of ASKUSER_READ_EVENT
+ * or ASKUSER_WRITE_EVENT or both.
+ * Special value ASKUSER_EMPTY_EVENTS indicates that the
+ * file descriptor (fd) should be removed from a file
+ * descriptor set of an event loop mechanism.
+ * \param[in] p_user_data User specific data passed to askuser_client_initialize().
+ */
+typedef void (*askuser_status_callback) (int fd, int events, void *p_user_data);
+
+/**
+ * \brief This callback function is called when a client receives a response
+ * upon calling askuser_client_popup_request().
+ *
+ * \attention This callback is called from the askuser_client_process() function context.
+ *
+ * \param[in] request_id A number identifying the request. It will be equal to
+ * the value of *p_request_id generated by a corresponding
+ * askuser_client_popup_request() function call.
+ * \param[in] cause A value representing the reason why this callback has
+ * been called.
+ * \param[in] result It is a result of response to request created by
+ * askuser_client_popup_request(). This should be
+ * interpreted as a valid value only if cause is equal to
+ * askuser_call_cause::ASKUSER_CALL_CAUSE_ANSWER.
+ * \param[in] p_user_data User specific data, this parameter was previously
+ * passed to askuser_client_popup_request().
+ */
+typedef void (*askuser_popup_response_callback) (int request_id,
+ askuser_call_cause cause,
+ askuser_popup_result result,
+ void *p_user_data);
+
+/**
+ * \brief Description
+ * Initialize askuser-notification client. It allocates structure and
+ * initializes it using a given status callback and user data.
+ *
+ * \par Purpose:
+ * This API function must be called prior to any call of the other
+ * askuser-notification client functions.
+ *
+ * \par Typical use case:
+ * It should be called before entering an event loop and before calling any
+ * other askuser-notification client API function.
+ *
+ * \par Method of function operation:
+ * This API function initializes inner library structures and in case of success
+ * returns askuser_client structure.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread-safety:
+ * This function is NOT thread-safe.
+ *
+ * \par Important notes:
+ * Structure askuser_client created by a askuser_client_initialize() call
+ * should be released by calling askuser_client_finalize().
+ *
+ * \param[out] pp_client A placeholder for a newly created askuser_client
+ * structure. The pp_client is valid only if this
+ * function returns ASKUSER_API_SUCCESS.
+ * \param[in] status_callback A callback function which will be called every
+ * time when some file descriptor belonging to the
+ * askuser_client structure changes its state.
+ * \param[in] p_user_data User specific data which will be passed to the
+ * status_callback function.
+ * Set NULL if you don't use user data.
+ *
+ * \return ASKUSER_API_SUCCESS on success
+ * \return a negative value in case of an error (see "Status return codes")
+ */
+int askuser_client_initialize(askuser_client **pp_client,
+ askuser_status_callback status_callback,
+ void *p_user_data);
+
+/**
+ * \brief Description
+ * Release instance of the askuser_client structure. It releases all resources
+ * associated with askuser_client structure.
+ *
+ * \par Purpose:
+ * This API function must be called to release all resources associated with
+ * askuser_client structure.
+ *
+ * \par Typical use case:
+ * This API function should be called when the askuser-notification client
+ * functionality is no more used by an application
+ * (e.g. when the application finishes).
+ *
+ * \par Method of function operation:
+ * This API function releases all internal resources and deallocates the
+ * askuser_client structure. When there are pending requests, registered
+ * askuser_response_callback functions will be called with an appropriate
+ * status code: askuser_call_cause::ASKUSER_CALL_CAUSE_FINALIZE.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread-safety:
+ * This function is NOT thread-safe.
+ *
+ * \par Important notes:
+ * After calling this function on a particular askuser_client structure,
+ * no subsequent calls of askuser_client_finalize() should be performed on
+ * the same structure.
+ *
+ * \param[out] p_client An instance of the askuser_client structure,
+ * previously created by askuser_client_initialize().
+ */
+void askuser_client_finalize(askuser_client *p_client);
+
+/**
+ * \brief Description
+ * This function process R/W events that occurred on a file descriptor associated
+ * with a specific askuser_client structure. All statuses and errors which occur
+ * on the file descriptor will be passed to a callback function registered by
+ * invoking askuser_client_initialize().
+ *
+ * \par Purpose:
+ * This API function is called to process read and write events which occurred
+ * on a file descriptor. In result of calling this function an appropriate
+ * callback is executed: askuser_status_callback or askuser_popup_response_callback.
+ *
+ * \par Typical use case:
+ * The event loop of an application waits for events which may occur on file descriptors
+ * previously registered by askuser_status_callback. When an event occurs then the event
+ * loop should call this function passing an askuser_client structure, a file
+ * descriptor on which the event occurred and events (a bit-field value compounds of
+ * ASKUSER_READ_EVENT and ASKUSER_WRITE_EVENT).
+ *
+ * \par Method of function operation:
+ * \parblock
+ * This function sends pending requests (ASKUSER_WRITE_EVENT), receives all responses
+ * from the askuser-notification service (ASKUSER_READ_EVENT). In result of these
+ * actions an appropriate callback is executed (askuser_popup_response_callback,
+ * or askuser_status_callback).
+ * \endparblock
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread-safety:
+ * This function is NOT thread-safe.
+ *
+ * \param[in] p_client An instance of the askuser_client structure, previously
+ * created by askuser_client_initialize().
+ * \param[in] fd A file descriptor.
+ * \param[in] events It is a bit-field value compounds of ASKUSER_READ_EVENT
+ * and ASKUSER_WRITE_EVENT, which represents the detected
+ * events on that fd. The event loop mechanism should
+ * pass **ASKUSER_EMPTY_EVENTS** if it detects an error
+ * on the file descriptor.
+ *
+ * \return ASKUSER_API_SUCCESS on success
+ * \return a negative value in case of an error (see "Status return codes")
+ */
+int askuser_client_process(askuser_client *p_client, int fd, int events);
+
+/**
+ * \brief Description
+ * This function is called to check if an application has access to a particular
+ * privilege.
+ *
+ * \par Purpose:
+ * This API function should be called if an application wants to check if it has
+ * access to a given privilege.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread-safety:
+ * This function is NOT thread-safe.
+ *
+ * \param[in] p_client An instance of the askuser_client structure previously
+ * created by askuser_client_initialize().
+ * \param[in] privilege Privilege that is to be checked.
+ * \param[out] p_result The result of a privilege check.
+ *
+ * \return ASKUSER_API_SUCCESS on success
+ * \return a negative value in case of an error (see "Status return codes")
+ */
+int askuser_client_check_privilege(askuser_client *p_client, const char *privilege,
+ askuser_check_result *p_result);
+
+/**
+ * \brief Description
+ * This function is called to determine a privacy privilege .
+ *
+ * \par Purpose:
+ * This API function should be called if an application wants to determine a privacy
+ * privilege. When this function is called, the askuser-notification service shows
+ * an appropriate UI dialog box (popup) with a question. After user's decision, the
+ * service modifies sends the response back to the application.
+ * The application is informed about user's decision by calling
+ * askuser_popup_response_callback.
+ *
+ * \par Method of function operation:
+ * If the result of calling askuser_client_check_privilege() is
+ * askuser_check_result::ASKUSER_CHECK_RESULT_ASK, the application should call
+ * this function to determine whether a user allows an application to use
+ * a particular privilege.
+ *
+ * \par Sync (or) Async:
+ * This is an asynchronous API.
+ *
+ * \par Thread-safety:
+ * This function is NOT thread-safe.
+ *
+ * \param[in] p_client An instance of the askuser_client structure
+ * previously created by askuser_client_initialize().
+ * \param[in] privilege A privilege for which a popup must be shown.
+ * \param[in] response_callback A callback function called when the API receives
+ * a response.
+ * \param[in] p_user_data User specific data which will be passed to
+ * the registered response_callback.
+ * Set to NULL if you don't use user data.
+ * \param[out] p_request_id An identifier of a request generated by the API.
+ * Set NULL if you don't use a request ID.
+ *
+ * \return ASKUSER_API_SUCCESS on success
+ * \return a negative value in case of an error (see "Status return codes")
+ */
+int askuser_client_popup_request(askuser_client *p_client, const char *privilege,
+ askuser_popup_response_callback response_callback,
+ void *p_user_data, int *p_request_id);
+
+/**
+ * Example
+ *
+ * NOTICE: Everything with app prefix is a part of a hypothetical
+ * application framework.
+ *
+ * \code
+ * void ask_status_callback(int fd, int events, void *p_user_data)
+ * {
+ * assert(p_user_data != NULL);
+ * app_context *app = (app_context *) p_user_data;
+ * // Note that events == 0 means that this fd should be
+ * // removed from a monitored file descriptor set.
+ * app_update_fds(app, fd, app_askuser_to_app_events(events));
+ * }
+ *
+ * void ask_popup_response_callback(int request_id, askuser_call_cause cause,
+ * askuser_popup_result result, void *p_user_data)
+ * {
+ * assert(p_user_data != NULL);
+ * app_context *app = (app_context *) p_user_data;
+ * app_callback callback = app_get_callback(app, request_id);
+ *
+ * switch (cause) {
+ * case ASKUSER_CALL_CAUSE_ANSWER:
+ * callback(app, askuser_to_app_popup_result(result));
+ * break;
+ * case ASKUSER_CALL_CAUSE_FINALIZE:
+ * callback(app, APP_IS_CLOSING);
+ * break;
+ * case ASKUSER_CALL_CAUSE_ERROR:
+ * // handle errors
+ * callback(app, APP_ASKUSER_ERROR_OCCURED);
+ * break;
+ * }
+ *
+ * app_unregister_callback(app, request_id);
+ * }
+ *
+ * void app_check_privilege(app_context *app, const char *privilege, app_callback callback);
+ * {
+ * int status;
+ * int request_id;
+ * askuser_check_result result;
+ *
+ * assert(app != NULL);
+ * askuser_client *client = app_get_askuser_client(app);
+ *
+ * status = askuser_client_check_privilege(client, &result);
+ * if (status != ASKUSER_API_SUCCESS) {
+ * // handle errors
+ * return;
+ * }
+ *
+ * switch (result) {
+ * case ASKUSER_CHECK_RESULT_ALLOW:
+ * // adjust GUI to reflect that the app has access to a
+ * // specific resource
+ * break;
+ * case ASKUSER_CHECK_RESULT_DENY:
+ * // adjust GUI to reflect that the app doesn't have access to a
+ * // specific resource
+ * break;
+ * case ASKUSER_CHECK_RESULT_ASK:
+ * status = askuser_client_popup_request(client, privilege,
+ * ask_popup_response_callback, app, &request_id);
+ * if (status != ASKUSER_API_SUCCESS) {
+ * //handle errors
+ * return;
+ * }
+ * app_register_callback(app, callback, request_id);
+ * break;
+ * }
+ * }
+ *
+ *
+ * void main_loop(app_context *app)
+ * {
+ * int status
+ * int fd;
+ * askuser_client *client = NULL;
+ *
+ * assert(app != NULL);
+ *
+ * status = askuser_client_initialize(&client, ask_status_callback, app);
+ * if (status != ASKUSER_API_SUCCESS) {
+ * // handle errors
+ * return;
+ * }
+ *
+ * app_set_askuser_client(app, client);
+ *
+ * // event loop
+ * for (;;) {
+ * app_wait_for_events(app);
+ *
+ * app_for_each_active_fd(app, fd) {
+ * if (app_is_askuser_fd(app, fd)) {
+ * app_events events = app_get_fd_events(app, fd);
+ * askuser_client_process(client, fd, app_to_askuser_events(events));
+ * }
+ * // process other file descriptors not related to askuser
+ * }
+ * }
+ *
+ * askuser_client_finalize(client);
+ * }
+ * \endcode
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASKUSER_NOTIFICATION_CLIENT_H */
--
2.7.4