summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanusz Kozerski <j.kozerski@samsung.com>2015-06-16 14:02:14 +0200
committerJanusz Kozerski <j.kozerski@samsung.com>2015-07-06 14:44:23 +0200
commitdb78d4705ab241499fe1ba438e15da514f4ec3ba (patch)
tree7fc49690eff5e0c8d1a5116d731ed85af665648e
parent263d2681b92f5d05726c1a2b7b5f4379a8f94646 (diff)
downloadcert-checker-db78d4705ab241499fe1ba438e15da514f4ec3ba.tar.gz
cert-checker-db78d4705ab241499fe1ba438e15da514f4ec3ba.tar.bz2
cert-checker-db78d4705ab241499fe1ba438e15da514f4ec3ba.zip
Add thread for processing events
Thread is waiting on conditional for events. When event will be add to queue the callback will send signal to thread (connman callback sends signal without adding event to queue). The thread: * Process the queue first: Moves all events from queue into the buffer. * Then process buffer (checks OCSP, shows popup, etc.) - to be implemented. Change-Id: I8cadc43b8d2c704bf07f0aec63b909ec4d52d5a7
-rw-r--r--src/include/cchecker/logic.h33
-rw-r--r--src/logic.cpp147
2 files changed, 171 insertions, 9 deletions
diff --git a/src/include/cchecker/logic.h b/src/include/cchecker/logic.h
index 3442890..1f42ab3 100644
--- a/src/include/cchecker/logic.h
+++ b/src/include/cchecker/logic.h
@@ -23,10 +23,12 @@
#ifndef CCHECKER_LOGIC_H
#define CCHECKER_LOGIC_H
+#include <condition_variable>
#include <gio/gio.h>
#include <string>
#include <vector>
#include <list>
+#include <thread>
#include <cchecker/app.h>
#include <cchecker/queue.h>
@@ -42,7 +44,8 @@ enum error_t {
REGISTER_CALLBACK_ERROR,
DBUS_ERROR,
PACKAGE_MANAGER_ERROR,
- DATABASE_ERROR
+ DATABASE_ERROR,
+ INTERNAL_ERROR
};
enum pkgmgr_event_t {
@@ -71,15 +74,19 @@ class Logic {
GVariant *parameters,
void *logic_ptr);
- private:
- //TODO: implement missing members
+ private:
error_t setup_db();
+ void load_database_to_buffer();
+
void check_ocsp(app_t &app);
void add_ocsp_url(const std::string &issuer, const std::string &url, int64_t date);
void pkgmanager_uninstall(const app_t &app);
void get_certs_from_signature(const std::string &signature, std::vector<std::string> &cert);
- void load_database_to_buffer();
+
+ void add_app_to_buffer(const app_t &app);
+ void remove_app_from_buffer(const app_t &app);
+
void pkgmgr_callback_internal(GVariant *parameters, pkgmgr_event_t event);
error_t register_dbus_signal_handler(GDBusProxy *proxy,
const char *name,
@@ -92,10 +99,28 @@ class Logic {
void *logic_ptr)
);
+ void process_all(void);
+ void process_queue(void);
+ void process_event(const event_t &event);
+ error_t process_buffer(void);
+
+ bool get_online(void) const;
+ void set_online(bool online);
+
+ bool get_should_exit(void) const;
+ void set_should_exit(void);
+
Queue m_queue;
std::list<app_t> m_buffer;
DB::SqlQuery *m_sqlquery;
+ bool m_was_setup_called;
+
bool m_is_online;
+ std::condition_variable m_to_process;
+ std::mutex m_mutex_cv;
+ std::thread m_thread;
+ bool m_should_exit;
+
GDBusProxy *m_proxy_connman;
GDBusProxy *m_proxy_pkgmgr_install;
GDBusProxy *m_proxy_pkgmgr_uninstall;
diff --git a/src/logic.cpp b/src/logic.cpp
index 8c25739..82059ac 100644
--- a/src/logic.cpp
+++ b/src/logic.cpp
@@ -38,6 +38,18 @@ const char *const TEPM_APP_ID = "temp#app_id";
Logic::~Logic(void)
{
LogDebug("Cert-checker cleaning.");
+
+ // wait and join processing thread
+ if (m_thread.joinable()) {
+ LogDebug("Waiting for join processing thread");
+ set_should_exit();
+ m_to_process.notify_one();
+ m_thread.join();
+ LogDebug("Processing thread joined");
+ }
+ else
+ LogDebug("No thread to join");
+
if (m_proxy_connman)
g_object_unref(m_proxy_connman);
if (m_proxy_pkgmgr_install)
@@ -49,12 +61,24 @@ Logic::~Logic(void)
Logic::Logic(void) :
m_sqlquery(NULL),
- m_is_online(false),
+ m_was_setup_called(false),
+ m_is_online(true),
+ m_should_exit(false),
m_proxy_connman(NULL),
m_proxy_pkgmgr_install(NULL),
m_proxy_pkgmgr_uninstall(NULL)
{}
+bool Logic::get_online() const
+{
+ return m_is_online;
+}
+
+void Logic::set_online(bool online)
+{
+ m_is_online = online;
+}
+
error_t Logic::setup_db()
{
// TODO: If database doesn't exist -should we create a new one?
@@ -75,6 +99,13 @@ error_t Logic::setup_db()
error_t Logic::setup()
{
+ // Check if setup was called
+ if (m_was_setup_called) {
+ LogError("You can call setup only once");
+ return INTERNAL_ERROR;
+ }
+ m_was_setup_called = true;
+
// Check if DB exists and create a new one if it doesn't
error_t err = setup_db();
if (err != NO_ERROR) {
@@ -82,6 +113,11 @@ error_t Logic::setup()
return err;
}
+ load_database_to_buffer();
+
+ // run process thread - thread will be waiting on condition variable
+ m_thread = std::thread(&Logic::process_all, this);
+
// FIXME: pkgmanager API signal handling was temporarily replaced
// by dbus API
@@ -121,8 +157,6 @@ error_t Logic::setup()
}
LogDebug("register connman event callback success");
- load_database_to_buffer();
-
return NO_ERROR;
}
@@ -243,6 +277,8 @@ void Logic::pkgmgr_callback_internal(GVariant *parameters,
", state: " << state << ", status: " << status);
m_queue.push_event(event_t(app, event_t::event_type_t::APP_UNINSTALL));
}
+
+ m_to_process.notify_one();
}
else
LogDebug("Wrong state (" << std::string(state) << ") or status (" << std::string(status) << ")");
@@ -272,11 +308,13 @@ void Logic::connman_callback(GDBusProxy */*proxy*/,
if (params_str == "('State', <'online'>)") {
LogDebug("Device online");
- logic->m_is_online = true;
+ logic->set_online(true);
+
+ logic->m_to_process.notify_one();
}
else if (params_str == "('State', <'offline'>)") {
LogDebug("Device offline");
- logic->m_is_online = false;
+ logic->set_online(false);
}
}
@@ -307,4 +345,103 @@ void Logic::load_database_to_buffer()
m_sqlquery->get_app_list(m_buffer);
}
+/**
+ * This function should move all event from queue to the buffer
+ **/
+void Logic::process_queue(void)
+{
+ event_t event;
+ while(m_queue.pop_event(event)) {
+ process_event(event);
+ }
+}
+
+error_t Logic::process_buffer(void)
+{
+ // TODO: Implement
+ return NO_ERROR;
+}
+
+void Logic::process_all()
+{
+ //Check if should't exit
+ while (!get_should_exit()) {
+ std::unique_lock<std::mutex> lock(m_mutex_cv);
+
+ if (m_queue.empty()) {
+ LogDebug("Processing thread: waiting on condition");
+ m_to_process.wait(lock);
+ }
+ else
+ LogDebug("Processing thread: More events in queue - processing again");
+
+ LogDebug("Processing thread: running");
+
+ process_queue();
+ if (get_online())
+ process_buffer();
+ else
+ LogDebug("No network. Buffer won't be processed");
+
+ LogDebug("Processing done");
+ }
+
+ // should process queue just before exit
+ process_queue();
+}
+
+void Logic::process_event(const event_t &event)
+{
+ if (event.event_type == event_t::event_type_t::APP_INSTALL) {
+ // TODO: implement geting app signature, then getting certificates from app signature.
+ // TODO: implement add app to buffer and database
+ add_app_to_buffer(event.app);
+ }
+ else if (event.event_type == event_t::event_type_t::APP_UNINSTALL) {
+ remove_app_from_buffer(event.app);
+ }
+ else
+ LogError("Unknown event type");
+}
+
+void Logic::add_app_to_buffer(const app_t &app)
+{
+ // First add app to DB
+ if(!m_sqlquery->add_app_to_check_list(app)) {
+ LogError("Failed to add " << app.str() << "to database");
+ // We can do nothing about it. We can only log the error.
+ }
+
+ // Then add app to buffer
+ m_buffer.push_back(app);
+}
+
+void Logic::remove_app_from_buffer(const app_t &app)
+{
+ // First remove app from DB
+ m_sqlquery->remove_app_from_check_list(app);
+
+ // Then remove app from buffer
+ for (auto iter = m_buffer.begin(); iter != m_buffer.end(); ++iter) {
+ if (iter->app_id == app.app_id &&
+ iter->pkg_id == app.pkg_id &&
+ iter->uid == app.uid) {
+ LogDebug(iter->str() << " found in buffer - will be removed");
+ m_buffer.erase(iter);
+ break;
+ }
+ }
+}
+
+bool Logic::get_should_exit(void) const
+{
+ return m_should_exit;
+}
+
+void Logic::set_should_exit(void)
+{
+ m_should_exit = true;
+
+}
+
} //CCHECKER