SET(ASKUSER_PATH ${PROJECT_SOURCE_DIR}/src)
-
+SET(TARGET_PLUGIN_SERVICE "askuser-plugin-service")
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_LIB_TEST "askuser-notification-test")
SET(TARGET_ASKUSER_NOTIFICATION_CLIENT_LIB "askuser-notification-client")
SET(TARGET_PRIVACY_PRIVILEGE_MANAGER_CAPI_LIB "capi-privacy-privilege-manager")
-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/ipc-lib)
ADD_SUBDIRECTORY(src/client)
ADD_SUBDIRECTORY(src/capi)
# @author Piotr Sawicki <p.sawicki2@partner.samsung.com>
#
+ADD_SUBDIRECTORY(askuser-notification)
ADD_SUBDIRECTORY(askuser-notification-client)
ADD_SUBDIRECTORY(capi-privacy-privilege-manager)
--- /dev/null
+# 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 <p.sawicki2@partner.samsung.com>
+#
+
+CONFIGURE_FILE(askuser-notification.pc.in askuser-notification.pc @ONLY)
+
+INSTALL(FILES
+ ${CMAKE_BINARY_DIR}/pkgconfig/askuser-notification/askuser-notification.pc
+ DESTINATION
+ ${LIB_INSTALL_DIR}/pkgconfig
+ )
--- /dev/null
+# 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
+Description: askuser-notification library
+Version: @ASKUSER_VERSION@
+Libs: -L${libdir} -laskuser-notification
+Cflags: -I${includedir}/askuser-notification
+++ /dev/null
-# 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 Dariusz Michaluk <d.michaluk@samsung.com>
-#
-
-SET(PROTOCOL_PATH ${ASKUSER_PATH}/common/protocol)
-
-SET(ASKUSER_NOTIFICATION_VERSION_MAJOR 0)
-SET(ASKUSER_NOTIFICATION_VERSION ${ASKUSER_NOTIFICATION_VERSION_MAJOR}.1.0)
-
-SET(PC_FILE "askuser-notification.pc")
-
-PKG_CHECK_MODULES(ASKUSER_NOTIFICATION_DEP
- REQUIRED
- libsystemd
- )
-
-INCLUDE_DIRECTORIES(
- ${PROTOCOL_PATH}
- SYSTEM
- ${ASKUSER_NOTIFICATION_DEP_INCLUDE_DIRS}
- )
-
-SET(ASKUSER_NOTIFICATION_SOURCES
- ${PROTOCOL_PATH}/channel.cpp
- ${PROTOCOL_PATH}/ask-user-client.cpp
- ${PROTOCOL_PATH}/sock.cpp
- ${PROTOCOL_PATH}/ask-user-config.cpp
- )
-
-SET(ASKUSER_NOTIFICATION_TEST_SOURCES
- ${PROTOCOL_PATH}/main.cpp
- )
-
-ADD_DEFINITIONS("-fvisibility=default")
-
-ADD_LIBRARY(${TARGET_ASKUSER_NOTIFICATION_LIB} SHARED ${ASKUSER_NOTIFICATION_SOURCES})
-ADD_EXECUTABLE(${TARGET_ASKUSER_NOTIFICATION_TEST} ${ASKUSER_NOTIFICATION_TEST_SOURCES})
-
-SET_TARGET_PROPERTIES(${TARGET_ASKUSER_NOTIFICATION_LIB}
- PROPERTIES
- SOVERSION ${ASKUSER_NOTIFICATION_VERSION_MAJOR}
- VERSION ${ASKUSER_NOTIFICATION_VERSION}
- OUTPUT_NAME "askuser-notification"
- )
-
-LINK_DIRECTORIES(${ASKUSER_NOTIFICATION_DEP_LIBRARY_DIRS})
-
-TARGET_LINK_LIBRARIES(${TARGET_ASKUSER_NOTIFICATION_LIB} ${ASKUSER_NOTIFICATION_DEP_LIBRARIES})
-TARGET_LINK_LIBRARIES(${TARGET_ASKUSER_NOTIFICATION_TEST} ${TARGET_ASKUSER_NOTIFICATION_LIB})
-
-INSTALL(TARGETS ${TARGET_ASKUSER_NOTIFICATION_LIB}
- DESTINATION ${LIB_INSTALL_DIR})
-
-CONFIGURE_FILE(${PC_FILE}.in ${PROTOCOL_PATH}/${PC_FILE} @ONLY)
-INSTALL(FILES ${PROTOCOL_PATH}/${PC_FILE}
- DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-
-FILE(GLOB HEADERS ${PROTOCOL_PATH}/askuser-notification/*.h)
-INSTALL(FILES ${HEADERS}
- DESTINATION ${INCLUDE_INSTALL_DIR}/askuser-notification)
-
-INSTALL(TARGETS ${TARGET_ASKUSER_NOTIFICATION_TEST}
- DESTINATION ${BIN_INSTALL_DIR})
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 ipc-client.cpp
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#include <sstream>
-#include <string>
-#include <vector>
-#include <memory>
-
-#include <askuser-notification/ask-user-client.h>
-#include <askuser-notification/ask-user-service.h>
-
-#include <ask-user-config.h>
-#include <sock.h>
-
-#define UNUSED __attribute__((unused))
-
-namespace AskUser {
-namespace Protocol {
-
-int popup_launch(const std::string &pkgName,
- const std::string &appName,
- uid_t uid,
- const PrivilegeVector &privileges,
- int &result)
-{
- try {
- Sock s(Sock::CLI_STREAM);
- if (0 > s.connect(getStreamSocketPath(uid)))
- return -1;
-
- std::stringstream ss;
- ss << MSGID_POPUP << " " << pkgName << " " << appName << " " << uid;
- for (auto &e : privileges) {
- ss << " " << e;
- }
-
- std::string str = ss.str();
-
- if (0 > s.send(RawBuffer(str.begin(), str.end())))
- return -1;
-
- RawBuffer resp;
- if (0 > s.wait(FdMask::READ))
- return -1;
- if (0 > s.recv(resp))
- return -1;
-
- std::string input(resp.begin(), resp.end());
- std::stringstream sss(input);
- sss >> result;
-
- return 0;
- } catch (const std::exception &) {
- return -1;
- }
-}
-
-int popup_runtime(UNUSED const std::string &pkgName,
- UNUSED const std::string &appName,
- UNUSED uid_t uid,
- UNUSED std::string &privilege,
- UNUSED int &result)
-{
- return -1;
-}
-
-
-int toast_deny(const std::string &pkgName,
- const std::string &appName,
- uid_t uid,
- const std::string &privilege)
-{
- try {
- Sock s(Sock::CLI_DGRAM);
- if (0 > s.connect(getDatagramSocketPath(uid)))
- return -1;
-
- std::string str = std::to_string(MSGID_TOAST1) + " " + pkgName + " " + appName + " " + std::to_string(uid) + " " + privilege;
-
- return s.send(RawBuffer(str.begin(), str.end()));
- } catch (const std::exception &) {
- return -1;
- }
-}
-
-int toast_fail_launch(const std::string &pkgName, const std::string &appName, uid_t uid) {
- try {
- Sock s(Sock::CLI_DGRAM);
- if (0 > s.connect(getDatagramSocketPath(uid)))
- return -1;
-
- std::string str = std::to_string(MSGID_TOAST2) + " " + pkgName + " " + appName + " " + std::to_string(uid);
-
- return s.send(RawBuffer(str.begin(), str.end()));
- } catch (const std::exception &) {
- return -1;
- }
-}
-
-} // namespace Protocol
-} // namespace AskUser
-
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 ask-user-config.cpp
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#include <ask-user-config.h>
-
-namespace {
-const std::string USER_EXT_PATH("/run/user_ext/");
-const std::string SOCKET_STREAM_NAME("/askuser-notification-stream.socket");
-const std::string SOCKET_DGRAM_NAME("/askuser-notification-datagram.socket");
-} // namespace anonymous
-
-std::string getDatagramSocketPath(uid_t uid) {
- return USER_EXT_PATH + std::to_string(uid) + SOCKET_DGRAM_NAME;
-}
-
-std::string getStreamSocketPath(uid_t uid) {
- return USER_EXT_PATH + std::to_string(uid) + SOCKET_STREAM_NAME;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 ask-user-config.h
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#pragma once
-
-#include <string>
-#include <sys/types.h>
-
-// We want to use it constat expressions (this is the reason why it's not in cpp file
-const int MSGID_POPUP = 1;
-const int MSGID_TOAST1 = 2;
-const int MSGID_TOAST2 = 3;
-
-std::string getDatagramSocketPath(uid_t uid);
-std::string getStreamSocketPath(uid_t uid);
-
+++ /dev/null
-# 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
-Description: askuser-notification library
-Version: @ASKUSER_NOTIFICATION_VERSION@
-Libs: -L${libdir} -laskuser-notification
-Cflags: -I${includedir}/askuser-notification
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 ask-user-client.h
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#pragma once
-
-#include <sys/types.h>
-
-#include <string>
-#include <vector>
-#include <memory>
-#include <askuser-notification/ask-user-types.h>
-
-namespace AskUser {
-namespace Protocol {
-/**
- * Synchronous request for showing popup.
- *
- * \param[in] pkgName Application package name.
- * \param[in] appName Application name.
- * \param[in] uid Information about user that should see popup.
- * \param[in] privileges List of privileges that should be shown to user.
- * \param[out] result Result returned by ask-user application.
- *
- * \return Value less that 0 means ipc error.
- */
- int popup_launch(const std::string &pkgName, const std::string &appName, uid_t uid, const PrivilegeVector &privileges, int &result);
-
- /**
- * Synchronous request for showing popup.
- *
- * \param[in] pkgName Application package name.
- * \param[in] appName Application name.
- * \param[in] uid Information about user that should see popup.
- * \param[in] privilege Privilege that should be shown to user.
- * \param[out] result Result returned by ask-user application.
- *
- * \return Value less that 0 means ipc error.
- */
- int popup_runtime(const std::string &pkgName, const std::string &appName, uid_t uid, std::string &privilege, int &result);
-
-/**
- * Nonblocking request for showing toast.
- *
- * \param[in] pkgName Application package name.
- * \param[in] appName Application name.
- * \param[in] uid Information about user that should see popup.
- * \param[in] privilege Name of privilege that was denied.
- *
- * \return Value less that 0 means ipc error.
- */
-int toast_deny(const std::string &pkgName, const std::string &appName, uid_t uid, const std::string &privilege);
-
-/**
- * Nonblocking request for showing toast.
- *
- * \param[in] pkgName Application package name.
- * \param[in] appName Application name.
- * \param[in] uid Information about user that should see popup.
- *
- * \return Value less that 0 means ipc error.
- */
-int toast_fail_launch(const std::string &pkgName, const std::string &appName, uid_t uid);
-
-} // namespace Protocol
-} // namespace AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 ask-user-service.h
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#pragma once
-
-#include <sys/types.h>
-
-#include <string>
-#include <vector>
-#include <memory>
-
-#include <askuser-notification/ask-user-types.h>
-
-namespace AskUser {
-namespace Protocol {
-
-typedef int ConnectionFd;
-typedef int RequestId;
-
-const ConnectionFd INVALID_FD = -1;
-const RequestId INVALID_ID = -1;
-
-enum FdMask {
- READ = 1,
- WRITE = 2,
-};
-
-struct Credentials {
- std::string label;
- uid_t uid;
-};
-
-/**
- * IServiceCallbacks defines set of callbacks that must be implemented in service.
- */
-
-struct IServerCallbacks {
-
- virtual ~IServerCallbacks(){}
- /**
- * This function is called when new peer connection is established.
- * Fd is file descriptor for this new peer connection.
- *
- * \param[in] fd Connection file descriptor
- */
- virtual void newConnection(ConnectionFd fd, const Credentials &creds) = 0;
-
- /**
- * This function gives you number of descriptor that should be watched by poll/select.
- *
- * \param[in] fd Connection file descriptor
- * \param[in] mask Type of acction that is required on this descriptor.
- * mask == 0 remove descriptor fd from watched pool
- * mask == 1 watch descriptor for READ
- * mask == 2 watch descriptor for WRITE
- * maks == 3 watch descriptor for READ and WRITE
- */
- virtual void updateConnection(ConnectionFd fd, int mask) = 0;
-
- /**
- * This function is called when popup request is received.
- *
- * \param[in] fd Connection file descriptor
- * \param[in] id Request identifier
- * \param[in] privilege Privilege for which permission is asked for
- */
- virtual void popup(ConnectionFd fd, RequestId id, std::string &&privilege) = 0;
-};
-
-struct IChannel {
- virtual ~IChannel(){}
-
- /**
- * Process function should be called each time some event is reported by poll/select on
- * descriptor.
- *
- * \param[in] fd Number of descriptor.
- * \param[in] mask Information about event that is waiting on descriptor
- * (FdMask::READ or FdMask::WRITE). If you pass 0 for some reason
- * the descriptor will be closed and callback updateFd will be called
- * with mask = 0
- */
- virtual void process(int fd, int mask) = 0;
-
- /**
- * Information about action that was chosen by user.
- *
- * \param[in] requestId Request number.
- * \param[in] response Information about action chosen by user.
- */
- virtual void popupResponse(ConnectionFd fd, RequestId id, int response) = 0;
-};
-
-typedef std::unique_ptr<IChannel> ChannelPtr;
-typedef std::unique_ptr<IServerCallbacks> ServerCallbacksPtr;
-
-ChannelPtr createChannel(ServerCallbacksPtr ptr);
-
-} // namespace Protocol
-} // namespace AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 ask-user-types.h
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#pragma once
-
-#define ASKUSER_NONE 0
-#define ASKUSER_DENY_ONCE 1
-#define ASKUSER_DENY_FOREVER 2
-#define ASKUSER_ALLOW_ONCE 3
-#define ASKUSER_ALLOW_FOREVER 4
-#define ASKUSER_UNKNOWN_ERROR -255
-
-namespace AskUser {
-namespace Protocol {
-
-typedef std::string Privilege;
-typedef std::vector<Privilege> PrivilegeVector;
-
-} // namespace Protocol
-} // AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 channel.cpp
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-
-#include <cstdlib>
-#include <string>
-#include <sstream>
-
-#include <askuser-notification/ask-user-service.h>
-
-#include <ask-user-config.h>
-#include <channel.h>
-#include <sock.h>
-
-namespace AskUser {
-namespace Protocol {
-
-void Channel::init() {
- Sock stream(Sock::SRV_STREAM);
- stream.connect(getStreamSocketPath(getuid()));
-
- int fd = stream.getFd();
- m_sockets[fd] = SockDesc(std::move(stream));
-
- m_callbacks->updateConnection(fd, FdMask::READ);
-}
-
-void Channel::parse(const std::string &data, std::vector<std::string> &parsedData)
-{
- size_t begin = 0;
-
- while (begin < data.size()) {
- size_t end = data.find(' ', begin);
-
- if (end == std::string::npos) {
- parsedData.push_back(data.substr(begin));
- return;
- }
-
- parsedData.push_back(data.substr(begin, end - begin));
- begin = end + 1;
- }
-}
-
-void Channel::process(int fd, int mask) {
- try {
- auto it = m_sockets.find(fd);
- if (it == m_sockets.end())
- return;
-
- if (0 == mask) {
- m_callbacks->updateConnection(fd, 0);
- m_sockets.erase(it);
- return;
- }
-
- auto &desc = it->second;
-
- if (desc.sock.getType() == Sock::SRV_STREAM) {
- Sock client = desc.sock.accept();
- int fd = client.getFd();
- if (fd < 0)
- return;
- m_sockets[fd] = SockDesc(std::move(client));
- m_callbacks->newConnection(fd, Credentials());
- m_callbacks->updateConnection(fd, FdMask::READ);
- return;
- }
-
- if (mask & FdMask::READ) {
- int ret = desc.sock.recv(desc.input);
-
- if (ret <= 0) {
- m_callbacks->updateConnection(fd, 0);
- m_sockets.erase(fd);
- return;
- }
-
- std::vector<std::string> params;
- parse(std::string(desc.input.begin(), desc.input.end()), params);
- desc.input.clear();
-
- int command = std::stoi(params[0]);
-
-
- switch (command) {
- case MSGID_POPUP:
- {
- std::string &privilege = params[1];
- RequestId id = std::strtol(params[2].c_str(), nullptr, 10);
- m_callbacks->popup(fd, id, std::move(privilege));
- break;
- }
- default :
- // TODO log the error
- m_callbacks->updateConnection(fd, 0);
- m_sockets.erase(fd);
- }
- }
-
- if (mask & FdMask::WRITE) {
- int size = static_cast<int>(desc.output.size());
- int result = desc.sock.send(desc.output);
- if (result < 0) {
- m_callbacks->updateConnection(fd, 0);
- m_sockets.erase(fd);
- return;
- }
-
- if (result == size) {
- desc.output.clear();
- m_callbacks->updateConnection(fd, FdMask::READ);
- }
-
- if (result < size) {
- desc.output.erase(desc.output.begin(), desc.output.begin()+result);
- }
- }
- } catch (const std::exception &){
- // TODO handle error
- }
-}
-
-void Channel::popupResponse(ConnectionFd fd, RequestId id, int response) {
- try {
- auto it = m_sockets.find(fd);
- if (it == m_sockets.end())
- return;
-
- auto &desc = it->second;
-
- std::stringstream ss;
- ss << id << " " << response;
- std::string o = ss.str();
- std::copy(o.begin(), o.end(), std::back_inserter(desc.output));
- m_callbacks->updateConnection(fd, FdMask::READ | FdMask::WRITE);
- } catch (const std::exception &){}
-}
-
-Channel::~Channel() {
- for (auto &e : m_sockets)
- m_callbacks->updateConnection(e.first, 0);
-}
-
-ChannelPtr createChannel(ServerCallbacksPtr ptr) {
- try {
- Channel *c = new Channel(std::move(ptr));
- c->init();
- return ChannelPtr(c);
- } catch (const std::exception &) {
- return ChannelPtr(nullptr);
- }
-}
-
-} // namespace Protocol
-} // namespace AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 channel.h
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#pragma once
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <askuser-notification/ask-user-service.h>
-
-#include <raw-buffer.h>
-#include <sock.h>
-
-
-namespace AskUser {
-namespace Protocol {
-
-struct SockDesc {
- SockDesc(Sock psock)
- : sock(std::move(psock))
- {}
- SockDesc(){}
- Sock sock;
- RawBuffer input;
- RawBuffer output;
-};
-
-typedef std::map<int, SockDesc> SocketMap;
-
-class Channel : public IChannel {
-public:
- Channel(ServerCallbacksPtr ptr)
- : m_callbacks(std::move(ptr))
- {}
-
- void init();
- virtual void process(ConnectionFd fd, int mask);
- virtual void popupResponse(ConnectionFd fd, RequestId id, int response);
- virtual ~Channel();
-
-private:
- virtual void parse(const std::string &data, std::vector<std::string> &parsedData);
-
- ServerCallbacksPtr m_callbacks;
- SocketMap m_sockets;
-};
-
-} // namespace Protocol
-} // namespace AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 main.cpp
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#include <map>
-
-#include <poll.h>
-#include <unistd.h>
-
-#include <askuser-notification/ask-user-client.h>
-#include <askuser-notification/ask-user-service.h>
-
-std::map<int, int> m_sockets;
-
-#define UNUSED __attribute__((unused))
-
-using namespace AskUser::Protocol;
-
-struct Callbacks : public IServerCallbacks {
- Callbacks() : m_channel(nullptr) {}
-
- virtual void newConnection(ConnectionFd fd, const Credentials &creds) {
- (void)fd;
- (void)creds;
- }
- virtual void updateConnection(ConnectionFd fd, int mask) {
- printf("call updateFd %d %d\n", fd, mask);
- if (mask == 0) {
- m_sockets.erase(fd);
- return;
- }
- m_sockets[fd] = mask;
- }
-
- virtual void popup(ConnectionFd fd, RequestId id, Privilege &&priv) {
- printf("call popup %s \n", priv.c_str());
- if (m_channel)
- m_channel->popupResponse(fd, id, 0xdeadbeef);
- }
-
- void setChannel(IChannel *ptr) {
- m_channel = ptr;
- }
-
-private:
- IChannel *m_channel;
-};
-
-void server(void) {
- Callbacks *c = new Callbacks;
- ChannelPtr ptr = createChannel(ServerCallbacksPtr(c));
- c->setChannel(ptr.get());
-
- pollfd fd[100];
-
- while(1) {
- int last = 0;
- for (auto &e : m_sockets) {
- fd[last].fd = e.first;
- fd[last].revents = 0;
- fd[last].events = ((e.second & FdMask::READ) ? POLLIN : 0) | ((e.second & FdMask::WRITE) ? POLLOUT : 0);
- last++;
- }
- if (-1 == poll(fd, last, -1)) {
- printf("Error in poll. Quit\n");
- return;
- }
- for (int i=0; i<last; ++i) {
- if (fd[i].revents & POLLIN)
- ptr->process(fd[i].fd, FdMask::READ);
- if (fd[i].revents & POLLOUT)
- ptr->process(fd[i].fd, FdMask::WRITE);
- }
- }
-}
-
-void stream() {
- PrivilegeVector vect = {"http://tizen.org/privilege/camera", "http://tizen.org/privilege/contacts"};
- int result;
- UNUSED int ret = popup_launch("org.tizen.memo", "org.tizen.memo", getuid(), vect, result);
- printf("Sended stream. Result: %x\n", result);
-}
-
-
-int main(){
- int com;
- printf("0 - server, 1 - send popup, 2 - send toust1, 3 - send toust2\n>");
- UNUSED int ret = scanf("%d", &com);
-
- switch(com) {
- case 0:
- server();
- break;
- case 1:
- stream();
- break;
- }
-
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 raw-buffer.h
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief
- */
-#pragma once
-
-#include <vector>
-
-namespace AskUser {
-namespace Protocol {
-
-typedef std::vector<unsigned char> RawBuffer;
-
-} // namespace Protocol
-} // namespace AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 Sock.cpp
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief Implementation of Sock methods
- */
-#include <poll.h>
-#include <stdexcept>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#ifdef BUILD_WITH_SYSTEMD_DAEMON
-#include <systemd/sd-daemon.h>
-#endif // BUILD_WITH_SYSTEMD_DAEMON
-
-#include <string>
-#include <vector>
-
-#include <askuser-notification/ask-user-service.h>
-
-#include <sock.h>
-
-namespace AskUser {
-namespace Protocol {
-
-Sock::Sock(Sock &&second)
- : m_type(second.m_type)
- , m_fd(second.m_fd)
-{
- second.m_fd = -1;
-}
-
-Sock::Sock(Sock::Type type, int fd)
- : m_type(type)
- , m_fd(fd)
-{}
-
-Sock& Sock::operator=(Sock &&second) {
- if (this == &second)
- return *this;
-
- close();
-
- m_fd = second.m_fd;
- m_type = second.m_type;
-
- second.m_fd = -1;
-
- return *this;
-}
-
-
-int Sock::getUnixSockType() const {
- switch(m_type) {
- case SRV_DGRAM:
- case CLI_DGRAM:
- return SOCK_DGRAM;
- case SRV_STREAM:
- case CLI_STREAM:
- return SOCK_STREAM;
- }
- return 0;
-}
-
-int Sock::getSocketFromSystemD() const {
-#ifdef BUILD_WITH_SYSTEMD_DAEMON
- int n = sd_listen_fds(0);
-
- if (n < 0)
- return -1;
-
- for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd)
- if (0 < sd_is_socket_unix(fd, getUnixSockType(), -1, m_path.c_str(), 0))
- return fd;
-#endif // BUILD_WITH_SYSTEMD_DAEMON
- return -1;
-}
-
-int Sock::connect(const std::string &path) {
- if (m_fd != -1)
- return -1;
-
- m_path = path;
-
- bool policySystemD = true;
- bool policyUnlink = true;
- bool policySocket = true;
- bool policyBind = true;
- bool policyListen = true;
- bool policyConnect = true;
-
- switch(m_type) {
- case SRV_STREAM:
- policyConnect = false;
- break;
- case CLI_STREAM:
- policySystemD = false;
- policyUnlink = false;
- policyBind = false;
- policyListen = false;
- break;
- case SRV_DGRAM:
- policyListen = false;
- policyConnect = false;
- break;
- case CLI_DGRAM:
- policySystemD = false;
- policyUnlink = false;
- policyBind = false;
- policyListen = false;
- policyConnect = false;
- break;
- }
-
- if (m_fd != -1) {
- return -1;
- }
-
- if (policySystemD) {
- m_fd = getSocketFromSystemD();
- if (m_fd >= 0) {
- policyUnlink = false;
- policySocket = false;
- policyBind = false;
- }
- }
-
- if (policyUnlink)
- ::unlink(m_path.c_str()); // we ignore return value by design
-
- if (policySocket)
- m_fd = ::socket(AF_UNIX, getUnixSockType(), 0);
-
- if (m_fd < 0)
- return -1;
-
- // remote is used in bind and in connect
- sockaddr_un remote;
- auto length = sizeof(sockaddr_un);
- if (policyBind || policyConnect) {
- remote.sun_family = AF_UNIX;
- if (path.size() >= sizeof(remote.sun_path)) {
- close();
- return -1;
- }
- memcpy(remote.sun_path, path.c_str(), path.size()+1);
- }
-
- if (policyBind && (-1 == ::bind(m_fd, reinterpret_cast<sockaddr *>(&remote), sizeof(remote)))) {
- close();
- return -1;
- }
-
- if (policyListen && (-1 == ::listen(m_fd, 5))) {
- close();
- return -1;
- }
-
- if (policyConnect && (-1 == TEMP_FAILURE_RETRY(::connect(m_fd, reinterpret_cast<sockaddr *>(&remote), static_cast<socklen_t>(length)))))
- {
- close();
- return -1;
- }
- return 0;
-}
-
-Sock Sock::accept() {
- int retFd = TEMP_FAILURE_RETRY(::accept(m_fd, nullptr, nullptr));
- if (retFd < 0) {
- return Sock(CLI_STREAM, -1);
- }
- return Sock(CLI_STREAM, retFd);
-}
-
-int Sock::send(const RawBuffer &buffer) {
- static const int flags = MSG_NOSIGNAL | MSG_DONTWAIT;
- if (m_fd < 0)
- return -1;
-
- switch(m_type) {
- default:
- return -1;
- case CLI_STREAM:
- {
- return static_cast<int>(
- TEMP_FAILURE_RETRY(::send(m_fd, buffer.data(), buffer.size(), flags)));
- }
- case CLI_DGRAM:
- {
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, m_path.data(), m_path.size());
- return static_cast<int>(
- TEMP_FAILURE_RETRY(::sendto(m_fd, buffer.data(), buffer.size(), flags,
- reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr))));
- }
- }
-}
-
-int Sock::wait(int mask) {
- pollfd fd = {0, 0, 0};
-
- fd.fd = m_fd;
- fd.events = (mask & FdMask::READ ? POLLIN : 0) | (mask & FdMask::WRITE ? POLLOUT : 0);
-
- if (fd.events == 0)
- return -1;
-
- if (0 > ::poll(&fd, 1, -1))
- return -1;
- return 0;
-}
-
-int Sock::recv(RawBuffer &output) {
- if (m_fd < 0)
- return -1;
-
- switch(m_type) {
- default:
- return -1;
- case CLI_STREAM:
- case SRV_DGRAM:
- {
- RawBuffer buffer(4096);
- int result = TEMP_FAILURE_RETRY(::recv(m_fd, buffer.data(), buffer.size(), MSG_DONTWAIT));
- if (result > 0)
- std::copy(buffer.begin(), buffer.begin()+result, std::back_inserter(output));
- return static_cast<int>(result);
- }
- }
-}
-
-void Sock::close() {
- if (m_fd >= 0)
- ::close(m_fd);
- m_fd = -1;
-}
-
-} // namespace Protocol
-} // namespace AskUser
-
+++ /dev/null
-/*
- * Copyright (c) 2017 Samsung Electronics Co.
- *
- * 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 Sock.cpp
- * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
- * @brief Declaration of client/server Sock wrapper
- */
-
-#pragma once
-
-#include <string>
-#include <unistd.h>
-
-#include <raw-buffer.h>
-
-namespace AskUser {
-namespace Protocol {
-
-class Sock {
-public:
- enum Type {
- SRV_STREAM, // server side STREAM socket (you may call accept on it)
- // accept will always return CLI_STREAM
- CLI_STREAM, // client side STREAM socket
- SRV_DGRAM, // server side DATAGRAM socket
- CLI_DGRAM, // client side DATAGRAM socket
- };
-
- Sock(Type type = SRV_STREAM, int fd = -1);
-
- Sock(const Sock &other) = delete;
- Sock &operator=(const Sock &other) = delete;
-
- Sock(Sock &&other);
- Sock &operator=(Sock &&other);
-
- virtual ~Sock() { close(); }
-
- int getFd() const { return m_fd; }
- int getType() const { return m_type; }
- int getUnixSockType() const;
-
- int connect(const std::string &path);
- Sock accept();
- void close();
-
- int wait(int mask);
- int recv(RawBuffer &buffer);
- int send(const RawBuffer &buffer);
-
-private:
- int getSocketFromSystemD() const;
-
- Type m_type;
- int m_fd;
- std::string m_path;
-};
-
-} // namespace Protocol
-} // namespace AskUser
-
--- /dev/null
+# 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 Dariusz Michaluk <d.michaluk@samsung.com>
+#
+
+SET(ASKUSER_NOTIFICATION_LIB_PATH ${ASKUSER_PATH}/ipc-lib)
+
+PKG_CHECK_MODULES(ASKUSER_NOTIFICATION_LIB_DEP
+ REQUIRED
+ libsystemd
+ )
+
+INCLUDE_DIRECTORIES(SYSTEM ${ASKUSER_NOTIFICATION_LIB_DEP_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(
+ ${ASKUSER_NOTIFICATION_LIB_PATH}
+ )
+
+SET(ASKUSER_NOTIFICATION_LIB_SOURCES
+ ${ASKUSER_NOTIFICATION_LIB_PATH}/ask-user-channel.cpp
+ ${ASKUSER_NOTIFICATION_LIB_PATH}/ask-user-client-channel.cpp
+ ${ASKUSER_NOTIFICATION_LIB_PATH}/sock.cpp
+ ${ASKUSER_NOTIFICATION_LIB_PATH}/ask-user-config.cpp
+ )
+
+SET(ASKUSER_NOTIFICATION_LIB_TEST_SOURCES
+ ${ASKUSER_NOTIFICATION_LIB_PATH}/test/main.cpp
+ )
+
+ADD_DEFINITIONS("-fvisibility=default")
+
+ADD_LIBRARY(${TARGET_ASKUSER_NOTIFICATION_LIB} SHARED ${ASKUSER_NOTIFICATION_LIB_SOURCES})
+ADD_EXECUTABLE(${TARGET_ASKUSER_NOTIFICATION_LIB_TEST} ${ASKUSER_NOTIFICATION_LIB_TEST_SOURCES})
+
+SET_TARGET_PROPERTIES(${TARGET_ASKUSER_NOTIFICATION_LIB}
+ PROPERTIES
+ SOVERSION ${ASKUSER_VERSION_MAJOR}
+ VERSION ${ASKUSER_VERSION}
+ OUTPUT_NAME "askuser-notification"
+ )
+
+LINK_DIRECTORIES(${ASKUSER_NOTIFICATION_LIB_DEP_LIBRARY_DIRS})
+
+TARGET_LINK_LIBRARIES(${TARGET_ASKUSER_NOTIFICATION_LIB} ${ASKUSER_NOTIFICATION_LIB_DEP_LIBRARIES})
+TARGET_LINK_LIBRARIES(${TARGET_ASKUSER_NOTIFICATION_LIB_TEST} ${TARGET_ASKUSER_NOTIFICATION_LIB})
+
+INSTALL(TARGETS ${TARGET_ASKUSER_NOTIFICATION_LIB}
+ DESTINATION ${LIB_INSTALL_DIR})
+
+FILE(GLOB HEADERS ${ASKUSER_NOTIFICATION_LIB_PATH}/askuser-notification/*.h)
+INSTALL(FILES ${HEADERS}
+ DESTINATION ${INCLUDE_INSTALL_DIR}/askuser-notification)
+
+INSTALL(TARGETS ${TARGET_ASKUSER_NOTIFICATION_LIB_TEST}
+ DESTINATION ${BIN_INSTALL_DIR})
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 channel.cpp
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+
+#include <cstdlib>
+#include <string>
+#include <sstream>
+
+#include <askuser-notification/ask-user-server-channel.h>
+#include <askuser-notification/sock.h>
+
+#include <ask-user-config.h>
+#include <ask-user-channel.h>
+
+namespace AskUser {
+namespace Protocol {
+
+void Channel::init() {
+ Sock stream(Sock::SRV_STREAM);
+ stream.connect(getStreamSocketPath(getuid()));
+
+ int fd = stream.getFd();
+ m_sockets[fd] = SockDesc(std::move(stream));
+
+ m_callbacks->updateConnection(fd, FdMask::READ);
+}
+
+void Channel::parse(const std::string &data, std::vector<std::string> &parsedData)
+{
+ size_t begin = 0;
+
+ while (begin < data.size()) {
+ size_t end = data.find(' ', begin);
+
+ if (end == std::string::npos) {
+ parsedData.push_back(data.substr(begin));
+ return;
+ }
+
+ parsedData.push_back(data.substr(begin, end - begin));
+ begin = end + 1;
+ }
+}
+
+void Channel::process(int fd, int mask) {
+ try {
+ auto it = m_sockets.find(fd);
+ if (it == m_sockets.end())
+ return;
+
+ if (0 == mask) {
+ m_callbacks->updateConnection(fd, 0);
+ m_sockets.erase(it);
+ return;
+ }
+
+ auto &desc = it->second;
+
+ if (desc.sock.getType() == Sock::SRV_STREAM) {
+ Sock client = desc.sock.accept();
+ int fd = client.getFd();
+ if (fd < 0)
+ return;
+ m_sockets[fd] = SockDesc(std::move(client));
+ m_callbacks->newConnection(fd, Credentials());
+ m_callbacks->updateConnection(fd, FdMask::READ);
+ return;
+ }
+
+ if (mask & FdMask::READ) {
+ int ret = desc.sock.recv(desc.input);
+
+ if (ret <= 0) {
+ m_callbacks->updateConnection(fd, 0);
+ m_sockets.erase(fd);
+ return;
+ }
+
+ std::vector<std::string> params;
+ parse(std::string(desc.input.begin(), desc.input.end()), params);
+ desc.input.clear();
+
+ int command = std::stoi(params[0]);
+
+
+ switch (command) {
+ case MSGID_POPUP:
+ {
+ std::string &privilege = params[1];
+ RequestId id = std::strtol(params[2].c_str(), nullptr, 10);
+ m_callbacks->popup(fd, id, std::move(privilege));
+ break;
+ }
+ default :
+ // TODO log the error
+ m_callbacks->updateConnection(fd, 0);
+ m_sockets.erase(fd);
+ }
+ }
+
+ if (mask & FdMask::WRITE) {
+ int size = static_cast<int>(desc.output.size());
+ int result = desc.sock.send(desc.output);
+ if (result < 0) {
+ m_callbacks->updateConnection(fd, 0);
+ m_sockets.erase(fd);
+ return;
+ }
+
+ if (result == size) {
+ desc.output.clear();
+ m_callbacks->updateConnection(fd, FdMask::READ);
+ }
+
+ if (result < size) {
+ desc.output.erase(desc.output.begin(), desc.output.begin()+result);
+ }
+ }
+ } catch (const std::exception &){
+ // TODO handle error
+ }
+}
+
+void Channel::popupResponse(ConnectionFd fd, RequestId id, int response) {
+ try {
+ auto it = m_sockets.find(fd);
+ if (it == m_sockets.end())
+ return;
+
+ auto &desc = it->second;
+
+ std::stringstream ss;
+ ss << id << " " << response;
+ std::string o = ss.str();
+ std::copy(o.begin(), o.end(), std::back_inserter(desc.output));
+ m_callbacks->updateConnection(fd, FdMask::READ | FdMask::WRITE);
+ } catch (const std::exception &){}
+}
+
+Channel::~Channel() {
+ for (auto &e : m_sockets)
+ m_callbacks->updateConnection(e.first, 0);
+}
+
+ChannelPtr createChannel(ServerCallbacksPtr ptr) {
+ try {
+ Channel *c = new Channel(std::move(ptr));
+ c->init();
+ return ChannelPtr(c);
+ } catch (const std::exception &) {
+ return ChannelPtr(nullptr);
+ }
+}
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 channel.h
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#pragma once
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <askuser-notification/ask-user-server-channel.h>
+#include <askuser-notification/raw-buffer.h>
+#include <askuser-notification/sock.h>
+
+
+namespace AskUser {
+namespace Protocol {
+
+struct SockDesc {
+ SockDesc(Sock psock)
+ : sock(std::move(psock))
+ {}
+ SockDesc(){}
+ Sock sock;
+ RawBuffer input;
+ RawBuffer output;
+};
+
+typedef std::map<int, SockDesc> SocketMap;
+
+class Channel : public IChannel {
+public:
+ Channel(ServerCallbacksPtr ptr)
+ : m_callbacks(std::move(ptr))
+ {}
+
+ void init();
+ virtual void process(ConnectionFd fd, int mask);
+ virtual void popupResponse(ConnectionFd fd, RequestId id, int response);
+ virtual ~Channel();
+
+private:
+ virtual void parse(const std::string &data, std::vector<std::string> &parsedData);
+
+ ServerCallbacksPtr m_callbacks;
+ SocketMap m_sockets;
+};
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 ipc-client.cpp
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#include <sstream>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <askuser-notification/ask-user-client-channel.h>
+#include <askuser-notification/ask-user-server-channel.h>
+#include <askuser-notification/sock.h>
+
+#include <ask-user-config.h>
+
+#define UNUSED __attribute__((unused))
+
+namespace AskUser {
+namespace Protocol {
+
+int popup_launch(const std::string &pkgName,
+ const std::string &appName,
+ uid_t uid,
+ const PrivilegeVector &privileges,
+ int &result)
+{
+ try {
+ Sock s(Sock::CLI_STREAM);
+ if (0 > s.connect(getStreamSocketPath(uid)))
+ return -1;
+
+ std::stringstream ss;
+ ss << MSGID_POPUP << " " << pkgName << " " << appName << " " << uid;
+ for (auto &e : privileges) {
+ ss << " " << e;
+ }
+
+ std::string str = ss.str();
+
+ if (0 > s.send(RawBuffer(str.begin(), str.end())))
+ return -1;
+
+ RawBuffer resp;
+ if (0 > s.wait(FdMask::READ))
+ return -1;
+ if (0 > s.recv(resp))
+ return -1;
+
+ std::string input(resp.begin(), resp.end());
+ std::stringstream sss(input);
+ sss >> result;
+
+ return 0;
+ } catch (const std::exception &) {
+ return -1;
+ }
+}
+
+int popup_runtime(UNUSED const std::string &pkgName,
+ UNUSED const std::string &appName,
+ UNUSED uid_t uid,
+ UNUSED std::string &privilege,
+ UNUSED int &result)
+{
+ return -1;
+}
+
+
+int toast_deny(const std::string &pkgName,
+ const std::string &appName,
+ uid_t uid,
+ const std::string &privilege)
+{
+ try {
+ Sock s(Sock::CLI_DGRAM);
+ if (0 > s.connect(getDatagramSocketPath(uid)))
+ return -1;
+
+ std::string str = std::to_string(MSGID_TOAST1) + " " + pkgName + " " + appName + " " + std::to_string(uid) + " " + privilege;
+
+ return s.send(RawBuffer(str.begin(), str.end()));
+ } catch (const std::exception &) {
+ return -1;
+ }
+}
+
+int toast_fail_launch(const std::string &pkgName, const std::string &appName, uid_t uid) {
+ try {
+ Sock s(Sock::CLI_DGRAM);
+ if (0 > s.connect(getDatagramSocketPath(uid)))
+ return -1;
+
+ std::string str = std::to_string(MSGID_TOAST2) + " " + pkgName + " " + appName + " " + std::to_string(uid);
+
+ return s.send(RawBuffer(str.begin(), str.end()));
+ } catch (const std::exception &) {
+ return -1;
+ }
+}
+
+} // namespace Protocol
+} // namespace AskUser
+
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 ask-user-config.cpp
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#include <ask-user-config.h>
+
+namespace {
+const std::string USER_EXT_PATH("/run/user_ext/");
+const std::string SOCKET_STREAM_NAME("/askuser-notification-stream.socket");
+const std::string SOCKET_DGRAM_NAME("/askuser-notification-datagram.socket");
+} // namespace anonymous
+
+std::string getDatagramSocketPath(uid_t uid) {
+ return USER_EXT_PATH + std::to_string(uid) + SOCKET_DGRAM_NAME;
+}
+
+std::string getStreamSocketPath(uid_t uid) {
+ return USER_EXT_PATH + std::to_string(uid) + SOCKET_STREAM_NAME;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 ask-user-config.h
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#pragma once
+
+#include <string>
+#include <sys/types.h>
+
+// We want to use it constat expressions (this is the reason why it's not in cpp file
+const int MSGID_POPUP = 1;
+const int MSGID_TOAST1 = 2;
+const int MSGID_TOAST2 = 3;
+
+std::string getDatagramSocketPath(uid_t uid);
+std::string getStreamSocketPath(uid_t uid);
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 ask-user-client.h
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#pragma once
+
+#include <sys/types.h>
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <askuser-notification/ask-user-types.h>
+
+namespace AskUser {
+namespace Protocol {
+/**
+ * Synchronous request for showing popup.
+ *
+ * \param[in] pkgName Application package name.
+ * \param[in] appName Application name.
+ * \param[in] uid Information about user that should see popup.
+ * \param[in] privileges List of privileges that should be shown to user.
+ * \param[out] result Result returned by ask-user application.
+ *
+ * \return Value less that 0 means ipc error.
+ */
+ int popup_launch(const std::string &pkgName, const std::string &appName, uid_t uid, const PrivilegeVector &privileges, int &result);
+
+ /**
+ * Synchronous request for showing popup.
+ *
+ * \param[in] pkgName Application package name.
+ * \param[in] appName Application name.
+ * \param[in] uid Information about user that should see popup.
+ * \param[in] privilege Privilege that should be shown to user.
+ * \param[out] result Result returned by ask-user application.
+ *
+ * \return Value less that 0 means ipc error.
+ */
+ int popup_runtime(const std::string &pkgName, const std::string &appName, uid_t uid, std::string &privilege, int &result);
+
+/**
+ * Nonblocking request for showing toast.
+ *
+ * \param[in] pkgName Application package name.
+ * \param[in] appName Application name.
+ * \param[in] uid Information about user that should see popup.
+ * \param[in] privilege Name of privilege that was denied.
+ *
+ * \return Value less that 0 means ipc error.
+ */
+int toast_deny(const std::string &pkgName, const std::string &appName, uid_t uid, const std::string &privilege);
+
+/**
+ * Nonblocking request for showing toast.
+ *
+ * \param[in] pkgName Application package name.
+ * \param[in] appName Application name.
+ * \param[in] uid Information about user that should see popup.
+ *
+ * \return Value less that 0 means ipc error.
+ */
+int toast_fail_launch(const std::string &pkgName, const std::string &appName, uid_t uid);
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 ask-user-service.h
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#pragma once
+
+#include <sys/types.h>
+
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <askuser-notification/ask-user-types.h>
+
+namespace AskUser {
+namespace Protocol {
+
+typedef int ConnectionFd;
+typedef int RequestId;
+
+const ConnectionFd INVALID_FD = -1;
+const RequestId INVALID_ID = -1;
+
+enum FdMask {
+ READ = 1,
+ WRITE = 2,
+};
+
+struct Credentials {
+ std::string label;
+ uid_t uid;
+};
+
+/**
+ * IServiceCallbacks defines set of callbacks that must be implemented in service.
+ */
+
+struct IServerCallbacks {
+
+ virtual ~IServerCallbacks(){}
+ /**
+ * This function is called when new peer connection is established.
+ * Fd is file descriptor for this new peer connection.
+ *
+ * \param[in] fd Connection file descriptor
+ */
+ virtual void newConnection(ConnectionFd fd, const Credentials &creds) = 0;
+
+ /**
+ * This function gives you number of descriptor that should be watched by poll/select.
+ *
+ * \param[in] fd Connection file descriptor
+ * \param[in] mask Type of acction that is required on this descriptor.
+ * mask == 0 remove descriptor fd from watched pool
+ * mask == 1 watch descriptor for READ
+ * mask == 2 watch descriptor for WRITE
+ * maks == 3 watch descriptor for READ and WRITE
+ */
+ virtual void updateConnection(ConnectionFd fd, int mask) = 0;
+
+ /**
+ * This function is called when popup request is received.
+ *
+ * \param[in] fd Connection file descriptor
+ * \param[in] id Request identifier
+ * \param[in] privilege Privilege for which permission is asked for
+ */
+ virtual void popup(ConnectionFd fd, RequestId id, std::string &&privilege) = 0;
+};
+
+struct IChannel {
+ virtual ~IChannel(){}
+
+ /**
+ * Process function should be called each time some event is reported by poll/select on
+ * descriptor.
+ *
+ * \param[in] fd Number of descriptor.
+ * \param[in] mask Information about event that is waiting on descriptor
+ * (FdMask::READ or FdMask::WRITE). If you pass 0 for some reason
+ * the descriptor will be closed and callback updateFd will be called
+ * with mask = 0
+ */
+ virtual void process(int fd, int mask) = 0;
+
+ /**
+ * Information about action that was chosen by user.
+ *
+ * \param[in] requestId Request number.
+ * \param[in] response Information about action chosen by user.
+ */
+ virtual void popupResponse(ConnectionFd fd, RequestId id, int response) = 0;
+};
+
+typedef std::unique_ptr<IChannel> ChannelPtr;
+typedef std::unique_ptr<IServerCallbacks> ServerCallbacksPtr;
+
+ChannelPtr createChannel(ServerCallbacksPtr ptr);
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 ask-user-types.h
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#pragma once
+
+#define ASKUSER_NONE 0
+#define ASKUSER_DENY_ONCE 1
+#define ASKUSER_DENY_FOREVER 2
+#define ASKUSER_ALLOW_ONCE 3
+#define ASKUSER_ALLOW_FOREVER 4
+#define ASKUSER_UNKNOWN_ERROR -255
+
+namespace AskUser {
+namespace Protocol {
+
+typedef std::string Privilege;
+typedef std::vector<Privilege> PrivilegeVector;
+
+} // namespace Protocol
+} // AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 raw-buffer.h
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief The declaration of RawBuffer.
+ */
+#pragma once
+
+#include <vector>
+
+namespace AskUser {
+namespace Protocol {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 sock.cpp
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief The declaration of client/server Sock wrapper.
+ */
+
+#pragma once
+
+#include <string>
+#include <unistd.h>
+
+#include <askuser-notification/raw-buffer.h>
+
+namespace AskUser {
+namespace Protocol {
+
+class Sock {
+public:
+ enum Type {
+ SRV_STREAM, // server side STREAM socket (you may call accept on it)
+ // accept will always return CLI_STREAM
+ CLI_STREAM, // client side STREAM socket
+ SRV_DGRAM, // server side DATAGRAM socket
+ CLI_DGRAM, // client side DATAGRAM socket
+ };
+
+ Sock(Type type = SRV_STREAM, int fd = -1);
+
+ Sock(const Sock &other) = delete;
+ Sock &operator=(const Sock &other) = delete;
+
+ Sock(Sock &&other);
+ Sock &operator=(Sock &&other);
+
+ virtual ~Sock() { close(); }
+
+ int getFd() const { return m_fd; }
+ int getType() const { return m_type; }
+ int getUnixSockType() const;
+
+ int connect(const std::string &path);
+ Sock accept();
+ void close();
+
+ int wait(int mask);
+ int recv(RawBuffer &buffer);
+ int send(const RawBuffer &buffer);
+
+private:
+ int getSocketFromSystemD() const;
+
+ Type m_type;
+ int m_fd;
+ std::string m_path;
+};
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 Sock.cpp
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief Implementation of Sock methods
+ */
+#include <poll.h>
+#include <stdexcept>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#ifdef BUILD_WITH_SYSTEMD_DAEMON
+#include <systemd/sd-daemon.h>
+#endif // BUILD_WITH_SYSTEMD_DAEMON
+
+#include <string>
+#include <vector>
+
+#include <askuser-notification/ask-user-server-channel.h>
+#include <askuser-notification/sock.h>
+
+namespace AskUser {
+namespace Protocol {
+
+Sock::Sock(Sock &&second)
+ : m_type(second.m_type)
+ , m_fd(second.m_fd)
+{
+ second.m_fd = -1;
+}
+
+Sock::Sock(Sock::Type type, int fd)
+ : m_type(type)
+ , m_fd(fd)
+{}
+
+Sock& Sock::operator=(Sock &&second) {
+ if (this == &second)
+ return *this;
+
+ close();
+
+ m_fd = second.m_fd;
+ m_type = second.m_type;
+
+ second.m_fd = -1;
+
+ return *this;
+}
+
+
+int Sock::getUnixSockType() const {
+ switch(m_type) {
+ case SRV_DGRAM:
+ case CLI_DGRAM:
+ return SOCK_DGRAM;
+ case SRV_STREAM:
+ case CLI_STREAM:
+ return SOCK_STREAM;
+ }
+ return 0;
+}
+
+int Sock::getSocketFromSystemD() const {
+#ifdef BUILD_WITH_SYSTEMD_DAEMON
+ int n = sd_listen_fds(0);
+
+ if (n < 0)
+ return -1;
+
+ for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd)
+ if (0 < sd_is_socket_unix(fd, getUnixSockType(), -1, m_path.c_str(), 0))
+ return fd;
+#endif // BUILD_WITH_SYSTEMD_DAEMON
+ return -1;
+}
+
+int Sock::connect(const std::string &path) {
+ if (m_fd != -1)
+ return -1;
+
+ m_path = path;
+
+ bool policySystemD = true;
+ bool policyUnlink = true;
+ bool policySocket = true;
+ bool policyBind = true;
+ bool policyListen = true;
+ bool policyConnect = true;
+
+ switch(m_type) {
+ case SRV_STREAM:
+ policyConnect = false;
+ break;
+ case CLI_STREAM:
+ policySystemD = false;
+ policyUnlink = false;
+ policyBind = false;
+ policyListen = false;
+ break;
+ case SRV_DGRAM:
+ policyListen = false;
+ policyConnect = false;
+ break;
+ case CLI_DGRAM:
+ policySystemD = false;
+ policyUnlink = false;
+ policyBind = false;
+ policyListen = false;
+ policyConnect = false;
+ break;
+ }
+
+ if (m_fd != -1) {
+ return -1;
+ }
+
+ if (policySystemD) {
+ m_fd = getSocketFromSystemD();
+ if (m_fd >= 0) {
+ policyUnlink = false;
+ policySocket = false;
+ policyBind = false;
+ }
+ }
+
+ if (policyUnlink)
+ ::unlink(m_path.c_str()); // we ignore return value by design
+
+ if (policySocket)
+ m_fd = ::socket(AF_UNIX, getUnixSockType(), 0);
+
+ if (m_fd < 0)
+ return -1;
+
+ // remote is used in bind and in connect
+ sockaddr_un remote;
+ auto length = sizeof(sockaddr_un);
+ if (policyBind || policyConnect) {
+ remote.sun_family = AF_UNIX;
+ if (path.size() >= sizeof(remote.sun_path)) {
+ close();
+ return -1;
+ }
+ memcpy(remote.sun_path, path.c_str(), path.size()+1);
+ }
+
+ if (policyBind && (-1 == ::bind(m_fd, reinterpret_cast<sockaddr *>(&remote), sizeof(remote)))) {
+ close();
+ return -1;
+ }
+
+ if (policyListen && (-1 == ::listen(m_fd, 5))) {
+ close();
+ return -1;
+ }
+
+ if (policyConnect && (-1 == TEMP_FAILURE_RETRY(::connect(m_fd, reinterpret_cast<sockaddr *>(&remote), static_cast<socklen_t>(length)))))
+ {
+ close();
+ return -1;
+ }
+ return 0;
+}
+
+Sock Sock::accept() {
+ int retFd = TEMP_FAILURE_RETRY(::accept(m_fd, nullptr, nullptr));
+ if (retFd < 0) {
+ return Sock(CLI_STREAM, -1);
+ }
+ return Sock(CLI_STREAM, retFd);
+}
+
+int Sock::send(const RawBuffer &buffer) {
+ static const int flags = MSG_NOSIGNAL | MSG_DONTWAIT;
+ if (m_fd < 0)
+ return -1;
+
+ switch(m_type) {
+ default:
+ return -1;
+ case CLI_STREAM:
+ {
+ return static_cast<int>(
+ TEMP_FAILURE_RETRY(::send(m_fd, buffer.data(), buffer.size(), flags)));
+ }
+ case CLI_DGRAM:
+ {
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ memcpy(addr.sun_path, m_path.data(), m_path.size());
+ return static_cast<int>(
+ TEMP_FAILURE_RETRY(::sendto(m_fd, buffer.data(), buffer.size(), flags,
+ reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr))));
+ }
+ }
+}
+
+int Sock::wait(int mask) {
+ pollfd fd = {0, 0, 0};
+
+ fd.fd = m_fd;
+ fd.events = (mask & FdMask::READ ? POLLIN : 0) | (mask & FdMask::WRITE ? POLLOUT : 0);
+
+ if (fd.events == 0)
+ return -1;
+
+ if (0 > ::poll(&fd, 1, -1))
+ return -1;
+ return 0;
+}
+
+int Sock::recv(RawBuffer &output) {
+ if (m_fd < 0)
+ return -1;
+
+ switch(m_type) {
+ default:
+ return -1;
+ case CLI_STREAM:
+ case SRV_DGRAM:
+ {
+ RawBuffer buffer(4096);
+ int result = TEMP_FAILURE_RETRY(::recv(m_fd, buffer.data(), buffer.size(), MSG_DONTWAIT));
+ if (result > 0)
+ std::copy(buffer.begin(), buffer.begin()+result, std::back_inserter(output));
+ return static_cast<int>(result);
+ }
+ }
+}
+
+void Sock::close() {
+ if (m_fd >= 0)
+ ::close(m_fd);
+ m_fd = -1;
+}
+
+} // namespace Protocol
+} // namespace AskUser
+
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co.
+ *
+ * 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 main.cpp
+ * @author Bartlomiej Grzelewski <b.grzelewski@samsung.com>
+ * @brief
+ */
+#include <map>
+
+#include <poll.h>
+#include <unistd.h>
+
+#include <askuser-notification/ask-user-client-channel.h>
+#include <askuser-notification/ask-user-server-channel.h>
+
+std::map<int, int> m_sockets;
+
+#define UNUSED __attribute__((unused))
+
+using namespace AskUser::Protocol;
+
+struct Callbacks : public IServerCallbacks {
+ Callbacks() : m_channel(nullptr) {}
+
+ virtual void newConnection(ConnectionFd fd, const Credentials &creds) {
+ (void)fd;
+ (void)creds;
+ }
+ virtual void updateConnection(ConnectionFd fd, int mask) {
+ printf("call updateFd %d %d\n", fd, mask);
+ if (mask == 0) {
+ m_sockets.erase(fd);
+ return;
+ }
+ m_sockets[fd] = mask;
+ }
+
+ virtual void popup(ConnectionFd fd, RequestId id, Privilege &&priv) {
+ printf("call popup %s \n", priv.c_str());
+ if (m_channel)
+ m_channel->popupResponse(fd, id, 0xdeadbeef);
+ }
+
+ void setChannel(IChannel *ptr) {
+ m_channel = ptr;
+ }
+
+private:
+ IChannel *m_channel;
+};
+
+void server(void) {
+ Callbacks *c = new Callbacks;
+ ChannelPtr ptr = createChannel(ServerCallbacksPtr(c));
+ c->setChannel(ptr.get());
+
+ pollfd fd[100];
+
+ while(1) {
+ int last = 0;
+ for (auto &e : m_sockets) {
+ fd[last].fd = e.first;
+ fd[last].revents = 0;
+ fd[last].events = ((e.second & FdMask::READ) ? POLLIN : 0) | ((e.second & FdMask::WRITE) ? POLLOUT : 0);
+ last++;
+ }
+ if (-1 == poll(fd, last, -1)) {
+ printf("Error in poll. Quit\n");
+ return;
+ }
+ for (int i=0; i<last; ++i) {
+ if (fd[i].revents & POLLIN)
+ ptr->process(fd[i].fd, FdMask::READ);
+ if (fd[i].revents & POLLOUT)
+ ptr->process(fd[i].fd, FdMask::WRITE);
+ }
+ }
+}
+
+void stream() {
+ PrivilegeVector vect = {"http://tizen.org/privilege/camera", "http://tizen.org/privilege/contacts"};
+ int result;
+ UNUSED int ret = popup_launch("org.tizen.memo", "org.tizen.memo", getuid(), vect, result);
+ printf("Sended stream. Result: %x\n", result);
+}
+
+
+int main(){
+ int com;
+ printf("0 - server, 1 - send popup, 2 - send toust1, 3 - send toust2\n>");
+ UNUSED int ret = scanf("%d", &com);
+
+ switch(com) {
+ case 0:
+ server();
+ break;
+ case 1:
+ stream();
+ break;
+ }
+
+ return 0;
+}
INCLUDE_DIRECTORIES(
${ASKUSER_PATH}
${ASKUSER_PATH}/common
- ${ASKUSER_PATH}/common/protocol
+ ${ASKUSER_PATH}/ipc-lib
${NOTIF_PATH}
)
#include <map>
#include <deque>
-#include <askuser-notification/ask-user-service.h>
+#include <askuser-notification/ask-user-server-channel.h>
#include <event/Event.h>
namespace AskUser {
#include <memory>
-#include <askuser-notification/ask-user-service.h>
+#include <askuser-notification/ask-user-server-channel.h>
#include "Logic.h"
#include "ui/Popupper.h"