summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanusz Kozerski <j.kozerski@samsung.com>2015-09-25 14:47:34 +0200
committerJanusz Kozerski <j.kozerski@samsung.com>2015-11-10 11:43:34 +0100
commit473de0fb27052aff62e4b391feb1b6447f83ec41 (patch)
treed8e7ddf77eb3e3424394fd0529b004a77dfd6b77
parent7871c1f106e6c11503b4a2a6f7bbbd876d2ec1fc (diff)
downloadcert-checker-473de0fb27052aff62e4b391feb1b6447f83ec41.tar.gz
cert-checker-473de0fb27052aff62e4b391feb1b6447f83ec41.tar.bz2
cert-checker-473de0fb27052aff62e4b391feb1b6447f83ec41.zip
Add popup
Since Notification framework doesn't support system daemons, the cert-checker's internal popup should be provided. Add implementation of popup binary - /usr/bin/cert-checker-popup Cert-checker forks(), execs a popup binary, waits for popup termination, and then reads user response from pipe. Change-Id: Ie2e70f661feb1f262841d59a1b4c6a7ec49901f9
-rw-r--r--CMakeLists.txt2
-rw-r--r--packaging/cert-checker.manifest3
-rw-r--r--packaging/cert-checker.spec12
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/dpl/core/include/cchecker/dpl/serialization.h496
-rw-r--r--src/dpl/core/src/serialization.cpp31
-rw-r--r--src/include/cchecker/UIBackend.h21
-rw-r--r--src/include/cchecker/popup-runner.h50
-rw-r--r--src/logic.cpp2
-rw-r--r--src/po/CMakeLists.txt2
-rw-r--r--src/po/en_GB.po14
-rw-r--r--src/po/en_US.po14
-rw-r--r--src/ui/CMakeLists.txt1
-rw-r--r--src/ui/UIBackend.cpp165
-rw-r--r--src/ui/popup-bin/CMakeLists.txt61
-rw-r--r--src/ui/popup-bin/popup.cpp296
-rw-r--r--src/ui/popup-bin/popup.h38
-rw-r--r--src/ui/popup-runner.cpp301
-rw-r--r--systemd/cert-checker.service3
-rw-r--r--tests/CMakeLists.txt6
-rw-r--r--tests/popup_test.cpp14
-rw-r--r--tests/stubs_.cpp3
22 files changed, 1360 insertions, 187 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6cbbc23..0f6baa2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,6 +59,8 @@ ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG")
ADD_DEFINITIONS("-DPOPUP=1")
SET(TARGET_CERT_CHECKER "cert-checker")
+SET(TARGET_CERT_CHECKER_POPUP "cert-checker-popup")
+# Tests
SET(TARGET_CERT_CHECKER_TESTS "cert-checker-tests")
SET(TARGET_CERT_CHECKER_TESTS_LOGIC "cert-checker-tests-logic")
SET(TARGET_CERT_CHECKER_POPUP_TEST "cert-checker-popup-test")
diff --git a/packaging/cert-checker.manifest b/packaging/cert-checker.manifest
index b91193d..75b0fa5 100644
--- a/packaging/cert-checker.manifest
+++ b/packaging/cert-checker.manifest
@@ -2,7 +2,4 @@
<request>
<domain name="_"/>
</request>
- <assign>
- <filesystem path="/usr/dbspace/.cert-checker.db" label="System"/>
- </assign>
</manifest>
diff --git a/packaging/cert-checker.spec b/packaging/cert-checker.spec
index 093401c..bfd5dc0 100644
--- a/packaging/cert-checker.spec
+++ b/packaging/cert-checker.spec
@@ -9,13 +9,14 @@ Source1: %{name}.manifest
BuildRequires: cmake
BuildRequires: zip
BuildRequires: gettext-tools
+BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(cert-svc-vcore)
BuildRequires: pkgconfig(db-util)
-BuildRequires: pkgconfig(icu-i18n)
-BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: pkgconfig(notification)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(dbus-glib-1)
-BuildRequires: pkgconfig(cert-svc-vcore)
+BuildRequires: pkgconfig(elementary)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(icu-i18n)
BuildRequires: pkgconfig(key-manager)
BuildRequires: pkgconfig(libsystemd-journal)
BuildRequires: pkgconfig(libtzplatform-config)
@@ -78,7 +79,7 @@ if [ $1 = 2 ]; then
# update
systemctl restart cert-checker.service
fi
-
+chsmack -a System %{TZ_SYS_DB}/.cert-checker.db
%preun
if [ $1 = 0 ]; then
@@ -95,6 +96,7 @@ fi
%files -f %{name}.lang
%{_bindir}/cert-checker
+%{_bindir}/cert-checker-popup
%manifest %{_datadir}/%{name}.manifest
%{_datadir}/license/%{name}
%config(noreplace) %attr(0600,root,root) %{TZ_SYS_DB}/.cert-checker.db
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e61cf4a..76a91d1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,13 +1,14 @@
PKG_CHECK_MODULES(CERT_CHECKER_DEP
REQUIRED
+ capi-appfw-application
cert-svc-vcore
dbus-1
dbus-glib-1
db-util
+ elementary
glib-2.0
gio-2.0
icu-i18n
- notification
key-manager
libsystemd-journal
libtzplatform-config
@@ -31,6 +32,7 @@ SET(CERT_CHECKER_SOURCES
${CERT_CHECKER_SRC_PATH}/dpl/core/src/exception.cpp
${CERT_CHECKER_SRC_PATH}/dpl/core/src/noncopyable.cpp
${CERT_CHECKER_SRC_PATH}/dpl/core/src/string.cpp
+ ${CERT_CHECKER_SRC_PATH}/dpl/core/src/serialization.cpp
# dpl DB
${CERT_CHECKER_SRC_PATH}/dpl/db/src/sql_connection.cpp
${CERT_CHECKER_SRC_PATH}/dpl/db/src/naive_synchronization_object.cpp
@@ -38,6 +40,7 @@ SET(CERT_CHECKER_SOURCES
${CERT_CHECKER_SRC_PATH}/db/sql_query.cpp
# UI
${CERT_CHECKER_SRC_PATH}/ui/UIBackend.cpp
+ ${CERT_CHECKER_SRC_PATH}/ui/popup-runner.cpp
)
INCLUDE_DIRECTORIES(SYSTEM
@@ -49,10 +52,17 @@ INCLUDE_DIRECTORIES(SYSTEM
ADD_EXECUTABLE(${TARGET_CERT_CHECKER} ${CERT_CHECKER_SOURCES})
+SET_TARGET_PROPERTIES(${TARGET_CERT_CHECKER} PROPERTIES
+ COMPILE_FLAGS
+ -fpie
+)
+
TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER}
${CERT_CHECKER_DEP_LIBRARIES}
+ -pie
)
INSTALL(TARGETS ${TARGET_CERT_CHECKER} DESTINATION ${BINDIR})
ADD_SUBDIRECTORY(po)
+ADD_SUBDIRECTORY(ui)
diff --git a/src/dpl/core/include/cchecker/dpl/serialization.h b/src/dpl/core/include/cchecker/dpl/serialization.h
new file mode 100644
index 0000000..5628350
--- /dev/null
+++ b/src/dpl/core/include/cchecker/dpl/serialization.h
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2011-2015 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 serialization.h
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 1.0
+ * @brief Interfaces and templates used for data serialization.
+ */
+#ifndef CCHECKER_SERIALIZATION_H
+#define CCHECKER_SERIALIZATION_H
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <memory>
+
+namespace CCHECKER {
+// Abstract data stream buffer
+class IStream
+{
+ public:
+ virtual void Read(size_t num, void * bytes) = 0;
+ virtual void Write(size_t num, const void * bytes) = 0;
+ virtual ~IStream(){}
+};
+
+// Serializable interface
+class ISerializable
+{
+ public:
+ /* ISerializable(){};
+ * ISerializable(IStream&){}; */
+ virtual void Serialize(IStream &) const = 0;
+ virtual ~ISerializable(){}
+};
+
+struct Serialization {
+ // serialization
+ // normal functions
+
+ // ISerializable objects
+ static void Serialize(IStream& stream, const ISerializable& object)
+ {
+ object.Serialize(stream);
+ }
+
+ static void Serialize(IStream& stream, const ISerializable* const object)
+ {
+ object->Serialize(stream);
+ }
+
+ // char
+ static void Serialize(IStream& stream, const char value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const char* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // unsigned char
+ static void Serialize(IStream& stream, const unsigned char value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const unsigned char* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // unsigned int32
+ static void Serialize(IStream& stream, const uint32_t value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const uint32_t* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // int32
+ static void Serialize(IStream& stream, const int32_t value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const int32_t* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // unsigned int64
+ static void Serialize(IStream& stream, const uint64_t value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const uint64_t* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // int64
+ static void Serialize(IStream& stream, const int64_t value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const int64_t* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // bool
+ static void Serialize(IStream& stream, const bool value)
+ {
+ stream.Write(sizeof(value), &value);
+ }
+ static void Serialize(IStream& stream, const bool* const value)
+ {
+ stream.Write(sizeof(*value), value);
+ }
+
+ // std::string
+ template <typename T, typename R, typename A>
+ static void Serialize(IStream& stream, const std::basic_string<T,R,A>& str)
+ {
+ int length = str.size();
+ stream.Write(sizeof(length), &length);
+ stream.Write(length*sizeof(T), str.data());
+ }
+
+ template<typename T, typename R, typename A>
+ static void Serialize(IStream& stream, const std::basic_string<T,R,A>* const str)
+ {
+ int length = str->size();
+ stream.Write(sizeof(length), &length);
+ stream.Write(length*sizeof(T), str->data());
+ }
+
+ // STL templates
+
+ // std::list
+ template <typename T>
+ static void Serialize(IStream& stream, const std::list<T>& list)
+ {
+ int length = list.size();
+ stream.Write(sizeof(length), &length);
+ for (typename std::list<T>::const_iterator list_iter = list.begin();
+ list_iter != list.end(); list_iter++)
+ {
+ Serialize(stream, *list_iter);
+ }
+ }
+ template <typename T>
+ static void Serialize(IStream& stream, const std::list<T>* const list)
+ {
+ Serialize(stream, *list);
+ }
+
+ // RawBuffer
+ template <typename A>
+ static void Serialize(IStream& stream, const std::vector<unsigned char, A>& vec)
+ {
+ int length = vec.size();
+ stream.Write(sizeof(length), &length);
+ stream.Write(length, vec.data());
+ }
+
+ template <typename A>
+ static void Serialize(IStream& stream, const std::vector<unsigned char, A>* const vec)
+ {
+ Serialize(stream, *vec);
+ }
+
+ // std::vector
+ template <typename T, typename A>
+ static void Serialize(IStream& stream, const std::vector<T, A>& vec)
+ {
+ int length = vec.size();
+ stream.Write(sizeof(length), &length);
+ for (const auto &i : vec)
+ {
+ Serialize(stream, i);
+ }
+ }
+ template <typename T, typename A>
+ static void Serialize(IStream& stream, const std::vector<T, A>* const vec)
+ {
+ Serialize(stream, *vec);
+ }
+
+ // std::pair
+ template <typename A, typename B>
+ static void Serialize(IStream& stream, const std::pair<A, B>& p)
+ {
+ Serialize(stream, p.first);
+ Serialize(stream, p.second);
+ }
+ template <typename A, typename B>
+ static void Serialize(IStream& stream, const std::pair<A, B>* const p)
+ {
+ Serialize(stream, *p);
+ }
+
+ // std::map
+ template <typename K, typename T>
+ static void Serialize(IStream& stream, const std::map<K, T>& map)
+ {
+ int length = map.size();
+ stream.Write(sizeof(length), &length);
+ typename std::map<K, T>::const_iterator it;
+ for (it = map.begin(); it != map.end(); ++it) {
+ Serialize(stream, (*it).first);
+ Serialize(stream, (*it).second);
+ }
+ }
+ template <typename K, typename T>
+ static void Serialize(IStream& stream, const std::map<K, T>* const map)
+ {
+ Serialize(stream, *map);
+ }
+
+ // std::unique_ptr
+ template <typename T>
+ static void Serialize(IStream& stream, const std::unique_ptr<T>& p)
+ {
+ Serialize(stream, *p);
+ }
+
+}; // struct Serialization
+
+struct Deserialization {
+ // deserialization
+ // normal functions
+
+ // ISerializable objects
+ // T instead of ISerializable is needed to call proper constructor
+ template <typename T>
+ static void Deserialize(IStream& stream, T& object)
+ {
+ object = T(stream);
+ }
+ template <typename T>
+ static void Deserialize(IStream& stream, T*& object)
+ {
+ object = new T(stream);
+ }
+
+ // char
+ static void Deserialize(IStream& stream, char& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, char*& value)
+ {
+ value = new char;
+ stream.Read(sizeof(*value), value);
+ }
+
+ // unsigned char
+ static void Deserialize(IStream& stream, unsigned char& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, unsigned char*& value)
+ {
+ value = new unsigned char;
+ stream.Read(sizeof(*value), value);
+ }
+
+ // unsigned int32
+ static void Deserialize(IStream& stream, uint32_t& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, uint32_t*& value)
+ {
+ value = new uint32_t;
+ stream.Read(sizeof(*value), value);
+ }
+
+ // int32
+ static void Deserialize(IStream& stream, int32_t& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, int32_t*& value)
+ {
+ value = new int32_t;
+ stream.Read(sizeof(*value), value);
+ }
+
+ // unsigned int64
+ static void Deserialize(IStream& stream, uint64_t& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, uint64_t*& value)
+ {
+ value = new uint64_t;
+ stream.Read(sizeof(*value), value);
+ }
+
+ // int64
+ static void Deserialize(IStream& stream, int64_t& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, int64_t*& value)
+ {
+ value = new int64_t;
+ stream.Read(sizeof(*value), value);
+ }
+
+ // bool
+ static void Deserialize(IStream& stream, bool& value)
+ {
+ stream.Read(sizeof(value), &value);
+ }
+ static void Deserialize(IStream& stream, bool*& value)
+ {
+ value = new bool;
+ stream.Read(sizeof(*value), value);
+ }
+
+ template <typename T, typename R, typename A>
+ static void Deserialize(IStream& stream, std::basic_string<T,R,A>& str)
+ {
+ int length;
+ stream.Read(sizeof(length), &length);
+ std::vector<T> buf(length);
+ stream.Read(length*sizeof(T), buf.data());
+ str = std::basic_string<T,R,A>(buf.data(), buf.data()+length);
+ }
+
+ template <typename T, typename R, typename A>
+ static void Deserialize(IStream& stream, std::basic_string<T,R,A>*& str)
+ {
+ int length;
+ stream.Read(sizeof(length), &length);
+ std::vector<T> buf(length);
+ stream.Read(length*sizeof(T), buf.data());
+ str = new std::basic_string<T,R,A>(buf.data(), buf.data()+length);
+ }
+
+ // STL templates
+
+ // std::list
+ template <typename T>
+ static void Deserialize(IStream& stream, std::list<T>& list)
+ {
+ int length;
+ stream.Read(sizeof(length), &length);
+ for (int i = 0; i < length; ++i) {
+ T obj;
+ Deserialize(stream, obj);
+ list.push_back(std::move(obj));
+ }
+ }
+ template <typename T>
+ static void Deserialize(IStream& stream, std::list<T>*& list)
+ {
+ list = new std::list<T>;
+ Deserialize(stream, *list);
+ }
+
+ // RawBuffer
+ template <typename A>
+ static void Deserialize(IStream& stream, std::vector<unsigned char, A>& vec)
+ {
+ int length;
+ stream.Read(sizeof(length), &length);
+ vec.resize(length);
+ stream.Read(length, vec.data());
+ }
+
+ template <typename A>
+ static void Deserialize(IStream& stream, std::vector<unsigned char, A>*& vec)
+ {
+ vec = new std::vector<unsigned char,A>;
+ Deserialize(stream, *vec);
+ }
+
+ // std::vector
+ template <typename T, typename A>
+ static void Deserialize(IStream& stream, std::vector<T,A>& vec)
+ {
+ int length;
+ stream.Read(sizeof(length), &length);
+ for (int i = 0; i < length; ++i) {
+ T obj;
+ Deserialize(stream, obj);
+ vec.push_back(std::move(obj));
+ }
+ }
+ template <typename T, typename A>
+ static void Deserialize(IStream& stream, std::vector<T,A>*& vec)
+ {
+ vec = new std::vector<T,A>;
+ Deserialize(stream, *vec);
+ }
+
+ // std::pair
+ template <typename A, typename B>
+ static void Deserialize(IStream& stream, std::pair<A, B>& p)
+ {
+ Deserialize(stream, p.first);
+ Deserialize(stream, p.second);
+ }
+ template <typename A, typename B>
+ static void Deserialize(IStream& stream, std::pair<A, B>*& p)
+ {
+ p = new std::pair<A, B>;
+ Deserialize(stream, *p);
+ }
+
+ // std::map
+ template <typename K, typename T>
+ static void Deserialize(IStream& stream, std::map<K, T>& map)
+ {
+ int length;
+ stream.Read(sizeof(length), &length);
+ for (int i = 0; i < length; ++i) {
+ K key;
+ T obj;
+ Deserialize(stream, key);
+ Deserialize(stream, obj);
+ map[key] = std::move(obj);
+ }
+ }
+ template <typename K, typename T>
+ static void Deserialize(IStream& stream, std::map<K, T>*& map)
+ {
+ map = new std::map<K, T>;
+ Deserialize(stream, *map);
+ }
+}; // struct Deserialization
+
+// generic serialization
+template <typename... Args>
+struct Serializer;
+
+template <typename First, typename... Args>
+struct Serializer<First, Args...> : public Serializer<Args...> {
+ static void Serialize(IStream& stream, const First& f, const Args&... args) {
+ Serialization::Serialize(stream, f);
+ Serializer<Args...>::Serialize(stream, args...);
+ }
+};
+
+// end of recursion
+template <>
+struct Serializer<> {
+ static void Serialize(IStream&) {
+ return;
+ }
+};
+
+// generic deserialization
+template <typename... Args>
+struct Deserializer;
+
+template <typename First, typename... Args>
+struct Deserializer<First, Args...> : public Deserializer<Args...> {
+ static void Deserialize(IStream& stream, First& f, Args&... args) {
+ Deserialization::Deserialize(stream, f);
+ Deserializer<Args...>::Deserialize(stream, args...);
+ }
+};
+
+// end of recursion
+template <>
+struct Deserializer<> {
+ static void Deserialize(IStream&) {
+ return;
+ }
+};
+
+} // CCHECKER
+
+#endif // CCHECKER_SERIALIZATION_H
diff --git a/src/dpl/core/src/serialization.cpp b/src/dpl/core/src/serialization.cpp
new file mode 100644
index 0000000..e7dbba7
--- /dev/null
+++ b/src/dpl/core/src/serialization.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file serialization.cpp
+ * @author Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version 1.0
+ * @brief This file is the implementation file of data serialization.
+ */
+#include <stddef.h>
+#include <cchecker/dpl/serialization.h>
+
+//
+// Note:
+//
+// The file here is left blank to enable precompilation
+// of templates in corresponding header file.
+// Do not remove this file.
+//
diff --git a/src/include/cchecker/UIBackend.h b/src/include/cchecker/UIBackend.h
index e59f0d7..6133078 100644
--- a/src/include/cchecker/UIBackend.h
+++ b/src/include/cchecker/UIBackend.h
@@ -21,24 +21,25 @@
#pragma once
-#include <notification.h>
-
#include <cchecker/app.h>
namespace CCHECKER {
namespace UI {
-enum response_e {
- DONT_UNINSTALL,
- UNINSTALL,
- ERROR
+enum popup_status : int {
+ NO_ERROR = 0,
+ EXIT_ERROR = 1
};
-// FIXME: notification framework is corrupted and it doesn't work as it should
+enum response_e : int {
+ DONT_UNINSTALL = 2,
+ UNINSTALL = 3,
+ RESPONSE_ERROR = 4
+};
class UIBackend {
public:
- explicit UIBackend(int timeout = 60); //timeout in seconds
+ explicit UIBackend(int timeout = 60); //timeout in seconds (zero or less means infinity)
virtual ~UIBackend();
// Displays popup with question, and - if needed - app_control for removing application.
@@ -48,10 +49,8 @@ public:
bool call_popup(const app_t &app);
private:
- response_e run();
- bool create_ui(const std::string &app_id, const std::string &pkg_id);
+ response_e run(const app_t &app);
- notification_h m_notification;
const int m_responseTimeout; // seconds
};
diff --git a/src/include/cchecker/popup-runner.h b/src/include/cchecker/popup-runner.h
new file mode 100644
index 0000000..addaa3b
--- /dev/null
+++ b/src/include/cchecker/popup-runner.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 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 popup-runner.h
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ */
+
+#include <vector>
+
+#include <cchecker/dpl/serialization.h>
+
+namespace CCHECKER{
+namespace UI{
+
+class BinaryStream : public CCHECKER::IStream {
+ public:
+ void Read (size_t num, void * bytes);
+ void Write(size_t num, const void * bytes);
+
+ BinaryStream();
+ ~BinaryStream();
+
+ const unsigned char* char_pointer() const;
+ size_t size() const;
+
+ private:
+ std::vector<unsigned char> m_data;
+ size_t m_readPosition;
+};
+
+response_e run_popup(
+ const app_t &app,
+ int timeout); // zero or negative timeout means infinity
+
+} // UI
+} // CCHECKER
diff --git a/src/logic.cpp b/src/logic.cpp
index 170f566..346a19c 100644
--- a/src/logic.cpp
+++ b/src/logic.cpp
@@ -21,7 +21,6 @@
*/
#include <stdexcept>
#include <tzplatform_config.h>
-#include <app_control_internal.h>
#include <cchecker/logic.h>
#include <cchecker/log.h>
@@ -429,7 +428,6 @@ bool Logic::process_app(app_t& app) {
app.verified = app_t::verified_t::NO;
#if POPUP
// Do not remove app here - just waits for user answer from popup
-// Temporary solution because notification framework doesn't work
return call_ui(app);
#else
return true;
diff --git a/src/po/CMakeLists.txt b/src/po/CMakeLists.txt
index 3cb076f..b89f4cb 100644
--- a/src/po/CMakeLists.txt
+++ b/src/po/CMakeLists.txt
@@ -17,7 +17,7 @@
#
SET(POFILES
- en.po pl.po
+ en.po en_GB.po en_US.po pl.po
)
SET(PREFIX ${CMAKE_INSTALL_PREFIX})
diff --git a/src/po/en_GB.po b/src/po/en_GB.po
new file mode 100644
index 0000000..764b151
--- /dev/null
+++ b/src/po/en_GB.po
@@ -0,0 +1,14 @@
+msgid "SID_TITLE_OCSP_VERIFICATION_FAILED"
+msgstr "OCSP verification failed"
+
+msgid "SID_CONTENT_OCSP_VERIFICATION_FAILED"
+msgstr "A certificate of an application %s (%s) was revoked."
+
+msgid "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED"
+msgstr "A certificate of one of applications in package %s was revoked."
+
+msgid "SID_BTN_OCSP_KEEP_APP"
+msgstr "Keep"
+
+msgid "SID_BTN_OCSP_UNINSTALL_APP"
+msgstr "Uninstall"
diff --git a/src/po/en_US.po b/src/po/en_US.po
new file mode 100644
index 0000000..764b151
--- /dev/null
+++ b/src/po/en_US.po
@@ -0,0 +1,14 @@
+msgid "SID_TITLE_OCSP_VERIFICATION_FAILED"
+msgstr "OCSP verification failed"
+
+msgid "SID_CONTENT_OCSP_VERIFICATION_FAILED"
+msgstr "A certificate of an application %s (%s) was revoked."
+
+msgid "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED"
+msgstr "A certificate of one of applications in package %s was revoked."
+
+msgid "SID_BTN_OCSP_KEEP_APP"
+msgstr "Keep"
+
+msgid "SID_BTN_OCSP_UNINSTALL_APP"
+msgstr "Uninstall"
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
new file mode 100644
index 0000000..4a31011
--- /dev/null
+++ b/src/ui/CMakeLists.txt
@@ -0,0 +1 @@
+ADD_SUBDIRECTORY(popup-bin) \ No newline at end of file
diff --git a/src/ui/UIBackend.cpp b/src/ui/UIBackend.cpp
index 5fd33a4..accac7c 100644
--- a/src/ui/UIBackend.cpp
+++ b/src/ui/UIBackend.cpp
@@ -19,185 +19,38 @@
* @brief This file implements class for ask user window
*/
-#include <bundle.h>
-#include <cerrno>
-#include <csignal>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <string>
-#include <libintl.h>
-#include <notification_internal.h>
-#include <notification_error.h>
-#include <app_control_internal.h>
+#include <app_control.h>
#include <cchecker/log.h>
#include <cchecker/UIBackend.h>
+#include <cchecker/popup-runner.h>
namespace CCHECKER {
namespace UI {
-namespace { // anonymus
-const char *errorToString(int error) {
- if (error == NOTIFICATION_ERROR_INVALID_PARAMETER)
- return "NOTIFICATION_ERROR_INVALID_PARAMETER";
- if (error == NOTIFICATION_ERROR_OUT_OF_MEMORY)
- return "NOTIFICATION_ERROR_OUT_OF_MEMORY";
- if (error == NOTIFICATION_ERROR_FROM_DB)
- return "NOTIFICATION_ERROR_FROM_DB";
- if (error == NOTIFICATION_ERROR_ALREADY_EXIST_ID)
- return "NOTIFICATION_ERROR_ALREADY_EXIST_ID";
- if (error == NOTIFICATION_ERROR_FROM_DBUS)
- return "NOTIFICATION_ERROR_FROM_DBUS";
- if (error == NOTIFICATION_ERROR_NOT_EXIST_ID)
- return "NOTIFICATION_ERROR_NOT_EXIST_ID";
- if (error == NOTIFICATION_ERROR_IO_ERROR)
- return "NOTIFICATION_ERROR_IO_ERROR";
- if (error == NOTIFICATION_ERROR_SERVICE_NOT_READY)
- return "NOTIFICATION_ERROR_SERVICE_NOT_READY";
- if (error == NOTIFICATION_ERROR_NONE)
- return "NOTIFICATION_ERROR_NONE";
-
- return "UNHANDLED ERROR";
-}
-} // anonymus
-
UIBackend::UIBackend(int timeout) :
- m_notification(nullptr),
m_responseTimeout(timeout)
{}
-UIBackend::~UIBackend() {
- notification_free(m_notification);
-}
-
-bool UIBackend::create_ui(const std::string &app_id, const std::string &pkg_id)
-{
- if(m_notification) {
- notification_free(m_notification);
- m_notification = nullptr;
- }
-
- m_notification = notification_create(NOTIFICATION_TYPE_NOTI);
- if (m_notification == nullptr) {
- LogError("Failed to create notification.");
- return false;
- }
-
- int err = notification_set_pkgname(m_notification, "cert-checker");
- if (err != NOTIFICATION_ERROR_NONE) {
- LogError("Unable to set notification pkgname: <" << errorToString(err) << ">");
- return false;
- }
-
- // Set title
- char *dialogTitle = dgettext(PROJECT_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED");
- err = notification_set_text(m_notification, NOTIFICATION_TEXT_TYPE_TITLE, dialogTitle, nullptr,
- NOTIFICATION_VARIABLE_TYPE_NONE);
- if (err != NOTIFICATION_ERROR_NONE) {
- LogError("Unable to set notification title: <" << errorToString(err) << ">");
- return false;
- }
-
- // Set message
- // App ID may be absent, so in that case we need to use only package ID
- if (app_id == std::string(TEMP_APP_ID)) {
- char *content = dgettext(PROJECT_NAME, "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED");
- err = notification_set_text(m_notification, NOTIFICATION_TEXT_TYPE_CONTENT, content, nullptr,
- NOTIFICATION_VARIABLE_TYPE_STRING, pkg_id.c_str(),
- NOTIFICATION_VARIABLE_TYPE_NONE);
- }
- else {
- char *content = dgettext(PROJECT_NAME, "SID_CONTENT_OCSP_VERIFICATION_FAILED");
- err = notification_set_text(m_notification, NOTIFICATION_TEXT_TYPE_CONTENT, content, nullptr,
- NOTIFICATION_VARIABLE_TYPE_STRING, app_id.c_str(),
- NOTIFICATION_VARIABLE_TYPE_STRING, pkg_id.c_str(),
- NOTIFICATION_VARIABLE_TYPE_NONE);
- }
- if (err != NOTIFICATION_ERROR_NONE) {
- LogError("Unable to set notification content: <" << errorToString(err) << ">");
- return false;
- }
-
- char *btn_keep = dgettext(PROJECT_NAME, "SID_BTN_OCSP_KEEP_APP");
- char *btn_uninstall = dgettext(PROJECT_NAME, "SID_BTN_OCSP_UNINSTALL_APP");
-
- std::string buttons = std::string(btn_keep) + std::string(",") + std::string(btn_uninstall);
-
- bundle *b = bundle_create();
- if (!b) {
- int erryes = errno;
- LogError("Unable to create bundle: <" << strerror(erryes) << ">");
- return false;
- }
-
- if (bundle_add(b, "buttons", buttons.c_str())) {
- int erryes = errno;
- LogError("Unable to add button to bundle: <" << strerror(erryes) << ">");
- bundle_free(b);
- return false;
- }
-
- err = notification_set_execute_option(m_notification, NOTIFICATION_EXECUTE_TYPE_RESPONDING,
- nullptr, nullptr, b);
- if (err != NOTIFICATION_ERROR_NONE) {
- LogError("Unable to set execute option: <" << errorToString(err) << ">");
- bundle_free(b);
- return false;
- }
- bundle_free(b);
-
- err = notification_insert(m_notification, nullptr);
- if (err != NOTIFICATION_ERROR_NONE) {
- LogError("Unable to insert notification: <" << errorToString(err) << ">");
- return false;
- }
-
- return true;
-}
+UIBackend::~UIBackend()
+{}
-response_e UIBackend::run()
+response_e UIBackend::run(const app_t &app)
{
- response_e response = response_e(ERROR);
- try {
- int buttonClicked = 0;
- int ret = notification_wait_response(m_notification, m_responseTimeout,
- &buttonClicked, nullptr);
- LogDebug("notification_wait_response finished with ret code: [" << ret << "]");
-
- if (ret == NOTIFICATION_ERROR_NONE) {
- // FIXME: magic numbers
- if (buttonClicked == 1) {
- response = response_e(DONT_UNINSTALL);
- LogDebug("notification_wait_response, button clicked: DON'T UNINSTALL");
- } else if (buttonClicked == 2) {
- response = response_e(UNINSTALL);
- LogDebug("notification_wait_response, Button clicked: UNINSTALL");
- } else {
- response = response_e(ERROR);
- LogError("notification_wait_response, timeouted");
- }
- }
- } catch (const std::exception &e) {
- LogError("Unexpected exception: <" << e.what() << ">");
- } catch (...) {
- LogError("Unexpected unknown exception caught!");
- }
- return response;
+ return run_popup(app, m_responseTimeout);
}
bool UIBackend::call_popup(const app_t &app)
{
response_e resp;
- create_ui(app.app_id, app.pkg_id);
- resp = run();
+ resp = run(app);
LogDebug(app.str() << " response: " << resp);
- if (resp == ERROR) {
+ if (resp == response_e::RESPONSE_ERROR) {
return false;
}
- else if (resp == UNINSTALL) {
+ else if (resp == response_e::UNINSTALL) {
app_control_h service = NULL;
int result = 0;
result = app_control_create(&service);
diff --git a/src/ui/popup-bin/CMakeLists.txt b/src/ui/popup-bin/CMakeLists.txt
new file mode 100644
index 0000000..a8bddfa
--- /dev/null
+++ b/src/ui/popup-bin/CMakeLists.txt
@@ -0,0 +1,61 @@
+# Copyright (c) 2015 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 Janusz Kozerski (j.kozerski@samsung.com)
+#
+# @version 1.0
+#
+
+PKG_CHECK_MODULES(CERT_CHECKER_POPUP_DEP
+ elementary
+ libsystemd-journal
+ REQUIRED)
+
+set(CERT_CHECKER_POPUP_SRC_DIR ${PROJECT_SOURCE_DIR}/src/ui/popup-bin)
+
+set(CERT_CHECKER_POPUP_SOURCES
+ ${CERT_CHECKER_POPUP_SRC_DIR}/popup.cpp
+ ${CERT_CHECKER_SRC_PATH}/ui/popup-runner.cpp
+ ${CERT_CHECKER_SRC_PATH}/app.cpp
+ # logs
+ ${CERT_CHECKER_SRC_PATH}/log/log.cpp
+ # dpl
+ ${CERT_CHECKER_SRC_PATH}/dpl/core/src/serialization.cpp
+)
+
+ADD_DEFINITIONS(${CERT_CHECKER_POPUP_DEP_CFLAGS})
+
+INCLUDE_DIRECTORIES(
+ ${CERT_CHECKER_POPUP_SRC_DIR}
+ ${CERT_CHECKER_POPUP_DEP_INCLUDE_DIRS}
+ ${CERT_CHECKER_SRC_PATH}/include/
+)
+
+ADD_EXECUTABLE(${TARGET_CERT_CHECKER_POPUP}
+ ${CERT_CHECKER_POPUP_SOURCES}
+)
+
+SET_TARGET_PROPERTIES(${TARGET_CERT_CHECKER_POPUP} PROPERTIES
+ COMPILE_FLAGS
+ -fpie
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_POPUP}
+ ${CERT_CHECKER_POPUP_DEP_LIBRARIES}
+ -pie
+)
+
+INSTALL(TARGETS ${TARGET_CERT_CHECKER_POPUP} DESTINATION ${BINDIR})
diff --git a/src/ui/popup-bin/popup.cpp b/src/ui/popup-bin/popup.cpp
new file mode 100644
index 0000000..6b3032a
--- /dev/null
+++ b/src/ui/popup-bin/popup.cpp
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2015 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 popup.cpp
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <vector>
+#include <libintl.h>
+#include <sys/select.h>
+#include <time.h>
+
+#include <Elementary.h>
+
+#include <popup.h>
+#include <cchecker/log.h>
+#include <cchecker/UIBackend.h>
+#include <cchecker/popup-runner.h>
+#include <cchecker/dpl/serialization.h>
+
+using namespace CCHECKER::UI;
+
+namespace { // anonymous
+
+void on_done(void) {
+ // Quit the efl-mainloop
+ LogDebug("elm_exit()");
+ elm_exit();
+}
+
+void keep_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) {
+
+ LogDebug("keep_answer");
+ if(NULL == data){
+ LogError("data is NULL; return");
+ return;
+ }
+ struct cert_checker_popup_data *pdp = static_cast <struct cert_checker_popup_data *> (data);
+ pdp->result = response_e::DONT_UNINSTALL;
+
+ on_done();
+}
+
+void uninstall_answer(void *data, Evas_Object * /* obj */, void * /* event_info */) {
+
+ LogDebug("uninstall_answer");
+ if(NULL == data){
+ LogError("data is NULL; return");
+ return;
+ }
+ struct cert_checker_popup_data *pdp = static_cast <struct cert_checker_popup_data *> (data);
+ pdp->result = response_e::UNINSTALL;
+
+ on_done();
+}
+
+void show_popup(struct cert_checker_popup_data *pdp) {
+ LogDebug("show_popup()");
+
+ if(NULL == pdp){
+ LogError("pdp is NULL; return");
+ return;
+ }
+
+ pdp->win = elm_win_add(NULL,
+ dgettext(PROJECT_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED"),
+ ELM_WIN_NOTIFICATION);
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+ elm_win_autodel_set(pdp->win, EINA_TRUE);
+ evas_object_show(pdp->win);
+ elm_win_indicator_opacity_set(pdp->win, ELM_WIN_INDICATOR_TRANSLUCENT);
+
+ pdp->popup = elm_popup_add(pdp->win);
+
+ pdp->box = elm_box_add(pdp->popup);
+ evas_object_size_hint_weight_set(pdp->box, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(pdp->box, EVAS_HINT_FILL, 0.0);
+
+ pdp->title = elm_label_add(pdp->popup);
+ elm_object_style_set(pdp->title, "elm.text.title");
+ elm_object_text_set(pdp->title, dgettext(PROJECT_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED"));
+ evas_object_show(pdp->title);
+ elm_box_pack_end(pdp->box, pdp->title);
+
+ pdp->content = elm_label_add(pdp->popup);
+ elm_object_style_set(pdp->content, "elm.swallow.content");
+ elm_label_line_wrap_set(pdp->content, ELM_WRAP_MIXED);
+
+ char *buff = NULL;
+ int ret;
+
+ // Set message
+ // App ID may be absent, so in that case we need to use only package ID
+ if (pdp->app_id == std::string(CCHECKER::TEMP_APP_ID)) {
+ char *content = dgettext(PROJECT_NAME, "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED");
+ ret = asprintf(&buff, content, pdp->pkg_id.c_str());
+ }
+ else {
+ char *content = dgettext(PROJECT_NAME, "SID_CONTENT_OCSP_VERIFICATION_FAILED");
+ ret = asprintf(&buff, content, pdp->app_id.c_str(), pdp->pkg_id.c_str());
+ }
+
+ if(-1 == ret){
+ LogError("asprintf failed - returned -1");
+ evas_object_del(pdp->content);
+ evas_object_del(pdp->popup);
+ evas_object_del(pdp->win);
+ return;
+ }
+ elm_object_text_set(pdp->content, buff);
+ LogDebug("Popup label: " << buff);
+ free(buff);
+ evas_object_size_hint_weight_set(pdp->content, EVAS_HINT_EXPAND, 0.0);
+ evas_object_size_hint_align_set(pdp->content, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(pdp->content);
+ elm_box_pack_end(pdp->box, pdp->content);
+
+ elm_object_part_content_set(pdp->popup, "default", pdp->box);
+
+ pdp->keep_button = elm_button_add(pdp->popup);
+ elm_object_style_set(pdp->keep_button, "elm.swallow.content.button1");
+ elm_object_text_set(pdp->keep_button, dgettext(PROJECT_NAME, "SID_BTN_OCSP_KEEP_APP"));
+ elm_object_part_content_set(pdp->popup, "button1", pdp->keep_button);
+ evas_object_smart_callback_add(pdp->keep_button, "clicked", keep_answer, pdp);
+
+ pdp->uninstall_button = elm_button_add(pdp->popup);
+ elm_object_style_set(pdp->uninstall_button, "elm.swallow.content.button2");
+ elm_object_text_set(pdp->uninstall_button, dgettext(PROJECT_NAME, "SID_BTN_OCSP_UNINSTALL_APP"));
+ elm_object_part_content_set(pdp->popup, "button2 ", pdp->uninstall_button);
+ evas_object_smart_callback_add(pdp->uninstall_button, "clicked", uninstall_answer, pdp);
+
+ evas_object_show(pdp->popup);
+
+ // Showing the popup window
+ evas_object_show(pdp->win);
+
+ // Run the efl mainloop
+ elm_run();
+
+ // Shutdown elementary
+ LogDebug("elm_shutdown()");
+ elm_shutdown();
+}
+
+static int wait_for_parent_info (int pipe_in)
+{
+ // wait for parameters from pipe_in
+ // timeout is set for 10 seconds
+ struct timeval timeout = {10L, 0L};
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(pipe_in, &readfds);
+
+ int sel = select(pipe_in + 1, &readfds, NULL, NULL, &timeout);
+ if (sel == -1) {
+ LogError("Cannot get info from parent. Exit popup - ERROR (" << errno << ")");
+ close(pipe_in);
+ return -1;
+ }
+ else if (sel == 0) {
+ LogError("Timeout reached! Exit popup - ERROR");
+ close(pipe_in);
+ return -1;
+ }
+ return 0;
+}
+
+void deserialize (cert_checker_popup_data *pdp, char *line, ssize_t line_length)
+{
+ BinaryStream stream;
+ stream.Write(line_length, static_cast <void *> (line));
+
+ std::string app_id;
+ std::string pkg_id;
+
+ LogDebug("------- Deserialization -------");
+ // Deserialization order:
+ // app_id, pkg_id
+
+ CCHECKER::Deserialization::Deserialize(stream, app_id);
+ LogDebug("app_id : " << app_id.c_str());
+ pdp->app_id = app_id.c_str();
+
+ CCHECKER::Deserialization::Deserialize(stream, pkg_id);
+ LogDebug("pkg_id : " << pkg_id.c_str());
+ pdp->pkg_id = pkg_id.c_str();
+}
+
+} // anonymous
+
+EAPI_MAIN int
+elm_main(int argc, char **argv)
+{
+ // int pipe_in and int pipe_out should be passed to Popup via args.
+
+ // These parameters should be passed to Popup via pipe_in:
+ // std::string app_id
+ // std::string pkg_id
+
+ struct cert_checker_popup_data pd;
+ struct cert_checker_popup_data *pdp = &pd;
+
+ LogDebug("############################ popup binary ################################");
+
+ setlocale(LC_ALL, "");
+
+ if(argc < 3){
+ LogError("To few args passed in exec to popup-bin - should be at least 3:");
+ LogError("(binary-name, pipe_in, pipe_out)");
+ LogError("return ERROR");
+ return popup_status::EXIT_ERROR;
+ }
+
+ LogDebug("Passed args: " << argv[0] <<", " << argv[1] << ", " << argv[2]);
+
+ int pipe_in;
+ int pipe_out;
+
+ // Parsing args (pipe_in, pipe_out)
+ if ( 0 == sscanf(argv[1], "%d", &pipe_in) ){
+ LogError("Error while parsing pipe_in; return ERROR");
+ return popup_status::EXIT_ERROR;
+ }
+ if ( 0 == sscanf(argv[2], "%d", &pipe_out) ){
+ LogError("Error while parsing pipe_out; return ERROR");
+ return popup_status::EXIT_ERROR;
+ }
+ LogDebug("Parsed pipes: IN: " << pipe_in <<", OUT: " << pipe_out);
+
+ if (wait_for_parent_info(pipe_in) == -1) {
+ close(pipe_out);
+ return popup_status::EXIT_ERROR;
+ }
+
+ int buff_size = 1024;
+ char line[buff_size];
+
+ ssize_t count = 0;
+
+ do {
+ count = TEMP_FAILURE_RETRY(read(pipe_in, line, buff_size));
+ } while (0 == count);
+ if(count < 0){
+ close(pipe_in);
+ close(pipe_out);
+ LogError("read returned a negative value (" << count <<")");
+ LogError("errno: " << strerror( errno ) );
+ LogError("Exit popup - ERROR");
+ return popup_status::EXIT_ERROR;
+ }
+ LogDebug("Read bytes : " << count);
+ close(pipe_in); // cleanup
+
+ deserialize(pdp, line, count);
+
+ pdp->result = response_e::RESPONSE_ERROR;
+
+ show_popup(pdp); // Showing popup
+
+ // sending validation_result to popup-runner
+ BinaryStream stream_out;
+
+ LogDebug("pdp->result : " << pdp->result);
+ CCHECKER::Serialization::Serialize(stream_out, pdp->result);
+ if(-1 == TEMP_FAILURE_RETRY(write(pipe_out, stream_out.char_pointer(), stream_out.size()))){
+ LogError("Write to pipe failed!");
+ close(pipe_out);
+ return popup_status::EXIT_ERROR;
+ }
+
+ close(pipe_out);
+
+ LogDebug("############################ /popup binary ################################");
+ LogDebug("Return: " << popup_status::NO_ERROR);
+ return popup_status::NO_ERROR;
+}
+ELM_MAIN()
diff --git a/src/ui/popup-bin/popup.h b/src/ui/popup-bin/popup.h
new file mode 100644
index 0000000..4a5d32a
--- /dev/null
+++ b/src/ui/popup-bin/popup.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015 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 popup.h
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ */
+
+#include <Elementary.h>
+
+#include <cchecker/UIBackend.h>
+
+struct cert_checker_popup_data {
+ std::string app_id;
+ std::string pkg_id;
+ CCHECKER::UI::response_e result;
+
+ Evas_Object *popup = NULL;
+ Evas_Object *win = NULL;
+ Evas_Object *box = NULL;
+ Evas_Object *title = NULL;
+ Evas_Object *content = NULL;
+ Evas_Object *keep_button = NULL;
+ Evas_Object *uninstall_button = NULL;
+};
diff --git a/src/ui/popup-runner.cpp b/src/ui/popup-runner.cpp
new file mode 100644
index 0000000..6411558
--- /dev/null
+++ b/src/ui/popup-runner.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2015 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 popup-runner.cpp
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <iostream>
+#include <sstream>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <cchecker/app.h>
+#include <cchecker/logic.h>
+#include <cchecker/log.h>
+#include <cchecker/UIBackend.h>
+#include <cchecker/popup-runner.h>
+
+namespace { // anonymous
+
+using namespace CCHECKER::UI;
+
+const char *POPUP_EXEC = "/usr/bin/cert-checker-popup"; // check-checker-popup binary
+
+std::string response_to_str (response_e response)
+{
+ switch (response) {
+ case response_e::DONT_UNINSTALL:
+ return "DONT_UNINSTALL";
+ case response_e::UNINSTALL:
+ return "UNINSTALL";
+ default:
+ return "RESPONSE_ERROR";
+ }
+}
+
+int wait_for_popup (int popup_pid, int timeout)
+{
+ int status;
+ int ret;
+
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ siginfo_t info;
+ struct timespec time = {timeout, 0L};
+
+ if (timeout > 0)
+ ret = TEMP_FAILURE_RETRY(sigtimedwait(&set, &info, &time));
+ else
+ ret = TEMP_FAILURE_RETRY(sigwaitinfo(&set, &info));
+
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+
+ if (ret == -1 && errno == EAGAIN) {
+ LogError("POPUP TIMEOUT");
+ goto err;
+ }
+ else if (ret == SIGCHLD && info.si_pid == popup_pid) {
+ // call waitpid on the child process to get rid of zombie process
+ waitpid(popup_pid, NULL, 0);
+
+ // The proper signal has been caught and its pid matches to popup_pid
+ // Now check the popup exit status
+ status = WEXITSTATUS(info.si_status);
+ LogDebug("STATUS EXIT ON POPUP (CHILD: " << info.si_pid << "): " << status);
+
+ switch (static_cast<popup_status>(status)) {
+
+ case popup_status::NO_ERROR:
+ LogDebug("NO_ERROR");
+ return 0;
+
+ case popup_status::EXIT_ERROR:
+ LogError("ERROR");
+ return -1;
+
+ default: // Unknown exit status
+ LogError("UNKNOWN_ERROR");
+ return -1;
+ }
+ }
+ else {
+ LogError("Some other signal has been caught (pid: " << info.si_pid << ", signal: " << info.si_signo << ")");
+ goto err;
+ }
+
+err:
+ // kill popup process and return error
+ kill(popup_pid, SIGKILL);
+
+ // call waitpid on the child process to get rid of zombie process
+ waitpid(popup_pid, NULL, 0);
+ return -1;
+}
+
+void child_process (int fd_send_to_child[2], int fd_send_to_parent[2])
+{
+ LogDebug("Child");
+
+ // read data from parent
+ close(fd_send_to_child[1]);
+
+ // send data to parent
+ close(fd_send_to_parent[0]);
+
+ std::stringstream pipe_in_buff;
+ std::stringstream pipe_out_buff;
+ pipe_in_buff << fd_send_to_parent[1];
+ pipe_out_buff << fd_send_to_child[0];
+ std::string pipe_in = pipe_in_buff.str();
+ std::string pipe_out = pipe_out_buff.str();
+
+ LogDebug("Passed file descriptors: " << fd_send_to_child[0] << ", "<< fd_send_to_parent[1]);
+
+ if (execl(POPUP_EXEC, POPUP_EXEC, pipe_out.c_str(), pipe_in.c_str(), NULL) < 0){
+ LogError("execl FAILED");
+ }
+
+ LogError("This should not happen!!!");
+ _exit(response_e::RESPONSE_ERROR);
+}
+
+int send_message_to_child(const BinaryStream &stream, int fd_send_to_child)
+{
+ LogDebug("Sending message to popup-bin process");
+ unsigned int begin = 0;
+ int tmp;
+ while (begin < stream.size()) {
+ tmp = TEMP_FAILURE_RETRY(write(fd_send_to_child,
+ stream.char_pointer() + begin,
+ stream.size() - begin));
+ if(-1 == tmp){
+ LogError("Write to pipe failed!");
+ return -1;
+ }
+ begin += tmp;
+ }
+ LogDebug("Message has been sent");
+ return 0;
+}
+
+response_e parse_response (int count, char *data)
+{
+ LogDebug("RESULT FROM POPUP PIPE (CHILD) : [ " << count << " ]");
+ int response_int;
+ response_e response;
+ BinaryStream stream_in;
+ stream_in.Write(count, data);
+ CCHECKER::Deserialization::Deserialize(stream_in, response_int);
+ response = static_cast <response_e> (response_int);
+ LogDebug("response :" << response_to_str(response));
+ return response;
+}
+
+} // anonymous namespace
+
+namespace CCHECKER {
+namespace UI {
+
+// BinaryStream class implementation
+void BinaryStream::Read(size_t num, void * bytes)
+{
+ size_t max_size = m_data.size();
+ for (size_t i = 0; i < num; ++i) {
+ if( i + m_readPosition >= max_size){
+ return;
+ }
+ static_cast <unsigned char*> (bytes)[i] = m_data[i + m_readPosition];
+ }
+ m_readPosition += num;
+}
+
+void BinaryStream::Write(size_t num, const void * bytes)
+{
+ for (size_t i = 0; i < num; ++i) {
+ m_data.push_back(static_cast <const unsigned char*> (bytes)[i]);
+ }
+}
+
+BinaryStream::BinaryStream() :
+ m_readPosition(0)
+{}
+
+BinaryStream::~BinaryStream() {}
+
+const unsigned char* BinaryStream::char_pointer() const
+{
+ return &m_data[0];
+}
+
+size_t BinaryStream::size() const
+{
+ return m_data.size();
+}
+// BinaryStream
+
+response_e run_popup(
+ const app_t &app,
+ int timeout)
+{
+ LogDebug(app.str());
+
+ // serialization
+ BinaryStream stream;
+ CCHECKER::Serialization::Serialize(stream, app.app_id);
+ CCHECKER::Serialization::Serialize(stream, app.pkg_id);
+
+ int fd_send_to_child[2];
+ int fd_send_to_parent[2];
+ pid_t childpid;
+
+ if(0 != pipe(fd_send_to_child)){
+ LogError("Cannot create pipes!");
+ return response_e::RESPONSE_ERROR;
+ }
+ if(0 != pipe(fd_send_to_parent)){
+ LogError("Cannot create pipes!");
+ close(fd_send_to_child[0]);
+ close(fd_send_to_child[1]);
+ return response_e::RESPONSE_ERROR;
+ }
+
+ if ((childpid = fork()) == -1) {
+ LogError("Fork() ERROR");
+ close(fd_send_to_child[0]);
+ close(fd_send_to_parent[1]);
+ goto error;
+ }
+
+ if(childpid == 0) { // Child process
+ child_process (fd_send_to_child, fd_send_to_parent);
+ }
+ else { // Parent process
+ LogDebug("Parent (child pid: " << childpid << ")");
+
+ // send data to child
+ close(fd_send_to_child[0]);
+
+ // read data from child
+ close(fd_send_to_parent[1]);
+
+ // writing to child
+ if (send_message_to_child(stream, fd_send_to_child[1]))
+ goto error;
+
+ // wait for child
+ if (wait_for_popup(childpid, timeout) != 0 )
+ goto error;
+
+ // Read message from popup (child)
+ int buff_size = 1024;
+ char result[buff_size];
+ int count;
+ count = TEMP_FAILURE_RETRY(read(fd_send_to_parent[0], result, buff_size));
+
+ // Parsing response from child
+ response_e response;
+ if (0 < count)
+ response = parse_response(count, result);
+ else {
+ LogDebug("ERROR, count = " << count);;
+ goto error;
+ }
+
+ LogDebug("popup-runner: EXIT SUCCESS");
+ // cleanup
+ close(fd_send_to_parent[0]);
+ close(fd_send_to_child[1]);
+ return response;
+ }
+
+ LogError("This should not happen!!!");
+error:
+ // cleanup
+ LogDebug("popup-runner: EXIT ERROR");
+ close(fd_send_to_parent[0]);
+ close(fd_send_to_child[1]);
+ return response_e::RESPONSE_ERROR;
+}
+
+} // UI
+} // CCHECKER
diff --git a/systemd/cert-checker.service b/systemd/cert-checker.service
index 58529b9..ba5fad7 100644
--- a/systemd/cert-checker.service
+++ b/systemd/cert-checker.service
@@ -3,6 +3,9 @@ Description=Start the Cert-Checker
Requires=dbus.service
[Service]
+EnvironmentFile=/etc/sysconfig/enlightenment
+# Makes popup bigger
+Environment="ELM_SCALE=4.0"
Type=simple
ExecStart=/usr/bin/cert-checker
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index ef836cd..511aeb9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,13 +1,14 @@
PKG_CHECK_MODULES(CERT_CHECKER_TESTS_DEP
REQUIRED
+ capi-appfw-application
cert-svc-vcore
+ db-util
dbus-1
dbus-glib-1
- db-util
+ elementary
glib-2.0
gio-2.0
icu-i18n
- notification
key-manager
libsystemd-journal
libtzplatform-config
@@ -76,6 +77,7 @@ SET(CERT_CHECKER_POPUP_TEST_SOURCES
${CERT_CHECKER_TESTS_SRC_PATH}/popup_test.cpp
# cert-checker
${CERT_CHECKER_SRC_PATH}/app.cpp
+ ${CERT_CHECKER_SRC_PATH}/ui/popup-runner.cpp
${CERT_CHECKER_SRC_PATH}/ui/UIBackend.cpp
# logs
${CERT_CHECKER_SRC_PATH}/log/log.cpp
diff --git a/tests/popup_test.cpp b/tests/popup_test.cpp
index e2e1e3d..d08747e 100644
--- a/tests/popup_test.cpp
+++ b/tests/popup_test.cpp
@@ -25,13 +25,19 @@
using namespace CCHECKER;
-int main(void)
+int main(int argc, char** argv)
{
- LogDebug("Cert-checker start!");
+ LogDebug("Cert-checker popup-test start!");
+
+ int timeout = 60;
+ if (argc > 1) {
+ timeout = atoi(argv[1]);
+ }
+ LogDebug("popup-test timeout: " << timeout);
setlocale(LC_ALL, "");
- UI::UIBackend ui(20); // timeout 20 seconds
+ UI::UIBackend ui(timeout);
app_t app(std::string("test_APP_ID"),
std::string("test PKG ID"),
@@ -40,6 +46,6 @@ int main(void)
ui.call_popup(app);
- LogDebug("Cert-checker exit!");
+ LogDebug("Cert-checker popup-test exit!");
return 0;
}
diff --git a/tests/stubs_.cpp b/tests/stubs_.cpp
index b475690..9eb8cfa 100644
--- a/tests/stubs_.cpp
+++ b/tests/stubs_.cpp
@@ -112,8 +112,7 @@ void DB::SqlQuery::get_app_list(std::list<app_t> &apps_buffer)
// UI
UI::UIBackend::UIBackend(int timeout) :
- m_notification(nullptr),
- m_responseTimeout(timeout)
+ m_responseTimeout(timeout)
{}
UI::UIBackend::~UIBackend()