aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTadao Tanikawa <tanikawa.tadao@jp.panasonic.com>2017-12-11 04:31:02 +0900
committerTadao Tanikawa <tanikawa.tadao@jp.panasonic.com>2017-12-11 04:31:02 +0900
commitcfb8bd8ca319adefe6001b823361acaf2fc1c32a (patch)
treeb3fea4eb0728db1fc6b5df0cdac62cdbf67a9132
parent901ee93f95c8a4ae9e5a10e1f2832d171ba546f6 (diff)
Change default method of app launch to fork/execv
Change-Id: I27f4261d6427d60cf3bf522478a52fc442028d8b Signed-off-by: Tadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
-rw-r--r--xdg-launcher/src/runxdg.cpp196
-rw-r--r--xdg-launcher/src/runxdg.hpp69
2 files changed, 205 insertions, 60 deletions
diff --git a/xdg-launcher/src/runxdg.cpp b/xdg-launcher/src/runxdg.cpp
index e3db8a1..8c984b1 100644
--- a/xdg-launcher/src/runxdg.cpp
+++ b/xdg-launcher/src/runxdg.cpp
@@ -26,14 +26,17 @@
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/wait.h>
#include <cstdio>
#include "runxdg.hpp"
-#define AFM_DBUS_SERVICE "org.AGL.afm.user"
-#define AFM_DBUS_PATH "/org/AGL/afm/user"
-#define AFM_DBUS_INTERFACE "org.AGL.afm.user"
+#ifdef TARGET_APP_PATH
+std::string target_app_path(TARGET_APP_PATH);
+#else
+std::string target_app_path("/usr/bin/weston-simple-egl");
+#endif
#ifdef TARGET_APP_ID
std::string target_app_id("\"" TARGET_APP_ID "\"");
@@ -86,19 +89,24 @@ void RunXDG::notify_ivi_control_cb (ilmObjectType object, t_ilm_uint id,
if (!created) {
AGL_DEBUG("ivi surface (id=%d, pid=%d) destroyed.", id, surf_pid);
- m_pgids.erase(surf_pid);
+ m_launcher->unregister_surfpid(surf_pid);
m_surfaces.erase(surf_pid);
return;
}
- register_surfpid(surf_pid);
- if (surf_pid == find_surfpid_by_rid(m_afm->m_rid)) {
- AGL_DEBUG("match: surf:pid=%d, afm:rid=%d", surf_pid, m_afm->m_rid);
+ AGL_DEBUG("ivi surface (id=%d, pid=%d) is created.", id, surf_pid);
+
+ m_launcher->register_surfpid(surf_pid);
+ if (surf_pid == m_launcher->find_surfpid_by_rid(m_launcher->m_rid)) {
+ AGL_DEBUG("match: surf:pid=%d, afm:rid=%d", surf_pid,
+ m_launcher->m_rid);
setup_surface(id);
+ } else {
+ AGL_DEBUG("Not match!!! %d %d", surf_pid,
+ m_launcher->find_surfpid_by_rid(m_launcher->m_rid));
}
m_surfaces[surf_pid] = id;
- AGL_DEBUG("ivi surface (id=%d, pid=%d) is created.", id, surf_pid);
} else if (object == ILM_LAYER) {
if (created)
AGL_DEBUG("ivi layer: %d created.", id);
@@ -114,7 +122,61 @@ void RunXDG::notify_ivi_control_cb_static (ilmObjectType object, t_ilm_uint id,
runxdg->notify_ivi_control_cb(object, id, created);
}
-int AFMDBus::get_dbus_message_bus (GBusType bus_type, GDBusConnection * &conn)
+int POSIXLauncher::launch (std::string &name)
+{
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0) {
+ AGL_DEBUG("cannot fork()");
+ return -1;
+ }
+
+ if (pid == 0) {
+ // child
+
+ char *const argv[2] = {
+ target_app_path.c_str(),
+ NULL, // test
+ };
+
+ AGL_DEBUG("execute %s", argv[0]);
+
+ execve(argv[0], argv, environ);
+
+ AGL_DEBUG("fail to execve()");
+ exit(EXIT_FAILURE);
+ } else {
+ AGL_DEBUG("fork [%s],pid=%d", target_app_path.c_str(), pid);
+ }
+
+ return pid;
+}
+
+void POSIXLauncher::loop (volatile sig_atomic_t* e_flag_p)
+{
+ int status;
+ pid_t ret;
+
+ ret = waitpid(m_rid, &status, 0);
+ if (ret < 0) {
+ AGL_DEBUG("fail to waitpid(%d)", m_rid);
+ return;
+ }
+
+ if (WIFEXITED(status)) {
+ AGL_DEBUG("%s terminated, return %d", target_app_path.c_str(),
+ WEXITSTATUS(status));
+ }
+
+ if (WIFSIGNALED(status)) {
+ AGL_DEBUG("%s terminated by signal %d", target_app_path.c_str(),
+ WTERMSIG(status));
+ }
+}
+
+int AFMDBusLauncher::get_dbus_message_bus (GBusType bus_type,
+ GDBusConnection * &conn)
{
GError* err = NULL;
@@ -128,7 +190,7 @@ int AFMDBus::get_dbus_message_bus (GBusType bus_type, GDBusConnection * &conn)
return 0;
}
-int AFMDBus::launch (std::string &name)
+int AFMDBusLauncher::launch (std::string &name)
{
GDBusMessage* msg;
GDBusMessage* re;
@@ -143,9 +205,9 @@ int AFMDBus::launch (std::string &name)
}
msg = g_dbus_message_new_method_call (
- AFM_DBUS_SERVICE,
- AFM_DBUS_PATH,
- AFM_DBUS_INTERFACE,
+ DBUS_SERVICE,
+ DBUS_PATH,
+ DBUS_INTERFACE,
"start");
if (msg == NULL) {
@@ -230,29 +292,30 @@ int RunXDG::init_wm (void)
return -1;
}
- std::function< void(json_object*) > h_active= [](json_object* object) {
+ std::function< void(json_object*) > h_active = [](json_object* object) {
AGL_DEBUG("Got Event_Active");
};
- std::function< void(json_object*) > h_inactive= [](json_object* object) {
+ std::function< void(json_object*) > h_inactive = [](json_object* object) {
AGL_DEBUG("Got Event_Inactive");
};
- std::function< void(json_object*) > h_visible= [](json_object* object) {
+ std::function< void(json_object*) > h_visible = [](json_object* object) {
AGL_DEBUG("Got Event_Visible");
};
- std::function< void(json_object*) > h_invisible= [](json_object* object) {
+ std::function< void(json_object*) > h_invisible = [](json_object* object) {
AGL_DEBUG("Got Event_Invisible");
};
- std::function< void(json_object*) > h_syncdraw = [this](json_object* object) {
- AGL_DEBUG("Got Event_SyncDraw");
- json_object* obj = json_object_new_object();
- json_object_object_add(obj, this->m_wm->kKeyDrawingName,
- json_object_new_string(app_name.c_str()));
- this->m_wm->endDraw(obj);
- };
+ std::function< void(json_object*) > h_syncdraw =
+ [this](json_object* object) {
+ AGL_DEBUG("Got Event_SyncDraw");
+ json_object* obj = json_object_new_object();
+ json_object_object_add(obj, this->m_wm->kKeyDrawingName,
+ json_object_new_string(app_name.c_str()));
+ this->m_wm->endDraw(obj);
+ };
std::function< void(json_object*) > h_flushdraw= [](json_object* object) {
AGL_DEBUG("Got Event_FlushDraw");
@@ -309,18 +372,28 @@ int RunXDG::init_hs (void)
return 0;
}
-RunXDG::RunXDG (int bus_type, int port, const char* &token)
+RunXDG::RunXDG (enum launcher_t type, int port, const char* &token)
{
m_port = port;
m_token = std::string(token);
- /* Setup API of AFM */
- if (bus_type == AFM_DBUS)
- m_afm = new AFMDBus();
- else
- m_afm = new AFMWebSocket();
+ /* Setup API of launcher */
+ switch (type) {
+ case POSIX:
+ m_launcher = new POSIXLauncher();
+ break;
+ case AFM_DBUS:
+ m_launcher = new AFMDBusLauncher();
+ break;
+ case AFM_WEBSOCKET:
+ m_launcher = new AFMWebSocketLauncher();
+ break;
+ default:
+ AGL_FATAL("Unknown type of launcher");
+ break;
+ }
- m_afm->m_rid = -1;
+ m_launcher->m_rid = -1;
// Setup HomeScreen/WindowManager API
if (init_wm())
@@ -362,7 +435,43 @@ void RunXDG::setup_surface (int id)
}
}
-void RunXDG::register_surfpid (pid_t surf_pid)
+void POSIXLauncher::register_surfpid (pid_t surf_pid)
+{
+ if (surf_pid == m_rid) {
+ if (!std::count(m_pid_v.begin(), m_pid_v.end(), surf_pid)) {
+ AGL_DEBUG("surface creator(pid=%d) registered", surf_pid);
+ m_pid_v.push_back(surf_pid);
+ AGL_DEBUG("m_pid_v.count(%d) = %d", surf_pid,
+ std::count(m_pid_v.begin(), m_pid_v.end(), surf_pid));
+ }
+ }
+}
+
+void POSIXLauncher::unregister_surfpid (pid_t surf_pid)
+{
+ auto itr = m_pid_v.begin();
+ while (itr != m_pid_v.end()) {
+ if (*itr == surf_pid) {
+ m_pid_v.erase(itr++);
+ } else {
+ ++itr;
+ }
+ }
+}
+
+pid_t POSIXLauncher::find_surfpid_by_rid (pid_t rid)
+{
+ AGL_DEBUG("find surfpid by rid(%d)", rid);
+ if (std::count(m_pid_v.begin(), m_pid_v.end(), rid)) {
+ AGL_DEBUG("found return(%d)", rid);
+ return rid;
+ }
+
+ AGL_DEBUG("Not found");
+ return -1;
+}
+
+void AFMLauncher::register_surfpid (pid_t surf_pid)
{
pid_t pgid = 0;
@@ -380,7 +489,7 @@ void RunXDG::register_surfpid (pid_t surf_pid)
}
}
-void RunXDG::unregister_surfpid (pid_t surf_pid)
+void AFMLauncher::unregister_surfpid (pid_t surf_pid)
{
auto itr = m_pgids.begin();
while (itr != m_pgids.end()) {
@@ -392,7 +501,7 @@ void RunXDG::unregister_surfpid (pid_t surf_pid)
}
}
-pid_t RunXDG::find_surfpid_by_rid (pid_t rid)
+pid_t AFMLauncher::find_surfpid_by_rid (pid_t rid)
{
auto itr = m_pgids.find(rid);
if (itr != m_pgids.end())
@@ -409,32 +518,31 @@ void RunXDG::start (void)
/* Launch XDG application */
pid_t rid;
- rid = m_afm->launch(target_app_id);
+ rid = m_launcher->launch(target_app_id);
if (rid < 0) {
AGL_FATAL("cannot launch XDG app (%s)", target_app_id);
}
- m_afm->m_rid = rid;
+ m_launcher->m_rid = rid;
// take care 1st time launch
AGL_DEBUG("waiting for notification: surafce created");
m_pending_create = true;
// in case, target app has already run
- pid_t surf_pid = find_surfpid_by_rid(m_afm->m_rid);
+ pid_t surf_pid = m_launcher->find_surfpid_by_rid(m_launcher->m_rid);
if (surf_pid > 0) {
- AGL_DEBUG("match: surf:pid=%d, afm:rid=%d", surf_pid, m_afm->m_rid);
+ AGL_DEBUG("match: surf:pid=%d, afm:rid=%d", surf_pid,
+ m_launcher->m_rid);
auto itr = m_surfaces.find(surf_pid);
if (itr != m_surfaces.end()) {
int id = itr->second;
- AGL_DEBUG("surface %d for <%s> already exists", id, app_name.c_str());
+ AGL_DEBUG("surface %d for <%s> already exists", id,
+ app_name.c_str());
setup_surface(id);
}
}
- /* sleep until terminate */
- while (!e_flag) {
- sleep(60*60*24);
- }
+ m_launcher->loop(&e_flag);
if (e_flag) {
AGL_DEBUG("recieved SIGTERM");
@@ -468,7 +576,7 @@ int main (int argc, const char* argv[])
}
AGL_DEBUG("port=%lu, token=[%s]", port, token);
- RunXDG runxdg(AFM_DBUS, port, token);
+ RunXDG runxdg(POSIX, port, token);
runxdg.start();
diff --git a/xdg-launcher/src/runxdg.hpp b/xdg-launcher/src/runxdg.hpp
index 2a94732..fa4ca0b 100644
--- a/xdg-launcher/src/runxdg.hpp
+++ b/xdg-launcher/src/runxdg.hpp
@@ -23,7 +23,9 @@
#define RUNXDG_HPP
#include <string>
+#include <vector>
#include <map>
+#include <algorithm>
#include <gio/gio.h>
@@ -56,38 +58,78 @@ class ILMControl
}
};
-class AFM
+enum launcher_t {
+ POSIX,
+ AFM_DBUS,
+ AFM_WEBSOCKET,
+};
+
+class Launcher
{
public:
+ virtual void register_surfpid(pid_t surf_pid) = 0;
+ virtual void unregister_surfpid(pid_t surf_pid) = 0;
+ virtual pid_t find_surfpid_by_rid(pid_t app_pid) = 0;
+
virtual int launch(std::string &name) = 0;
+ virtual void loop(volatile sig_atomic_t* e_flag) = 0;
int m_rid;
};
-class AFMDBus : public AFM
+class POSIXLauncher : public Launcher
+{
+ private:
+ std::vector<pid_t> m_pid_v;
+
+ public:
+ void register_surfpid(pid_t surf_pid);
+ void unregister_surfpid(pid_t surf_pid);
+ pid_t find_surfpid_by_rid(pid_t rid);
+
+ int launch(std::string &name);
+ void loop(volatile sig_atomic_t* e_flag);
+};
+
+class AFMLauncher : public Launcher
+{
+ private:
+ std::map<int, int> m_pgids; // pair of <afm:rid, ivi:pid>
+
+ public:
+ void register_surfpid(pid_t surf_pid);
+ void unregister_surfpid(pid_t surf_pid);
+ pid_t find_surfpid_by_rid(pid_t app_pid);
+};
+
+class AFMDBusLauncher : public AFMLauncher
{
public:
int launch(std::string &name);
+ void loop(volatile sig_atomic_t* e_flag) {
+ while (!(*e_flag)) { sleep(60*60*24); } }
+
private:
- int get_dbus_message_bus(GBusType bus_type, GDBusConnection* &conn);
+ int get_dbus_message_bus(GBusType bus_type, GDBusConnection* &conn);
+
+ const char* DBUS_SERVICE = "org.AGL.afm.user";
+ const char* DBUS_PATH = "/org/AGL/afm/user";
+ const char* DBUS_INTERFACE = "org.AGL.afm.user";
};
-class AFMWebSocket : public AFM
+class AFMWebSocketLauncher : public AFMLauncher
{
// not implemented yet
public:
int launch(std::string &name) { return 0; }
-};
-
-enum {
- AFM_DBUS,
- AFM_WEBSOCKET,
+ void loop(volatile sig_atomic_t* e_flag) {
+ while (!(*e_flag)) { sleep(60*60*24); } }
};
class RunXDG
{
public:
- RunXDG(int bus_type, int port, const char* &token);
+ RunXDG(enum launcher_t type, int port, const char* &token);
void start(void);
void notify_ivi_control_cb(ilmObjectType object, t_ilm_uint id,
@@ -101,14 +143,13 @@ class RunXDG
int m_port;
std::string m_token;
- AFM *m_afm;
+ Launcher *m_launcher;
LibWindowmanager *m_wm;
LibHomeScreen *m_hs;
ILMControl *m_ic;
std::map<int, int> m_surfaces; // pair of <afm:rid, ivi:id>
- std::map<int, int> m_pgids; // pair of <afm:rid, ivi:pid>
bool m_pending_create = false;
@@ -116,10 +157,6 @@ class RunXDG
int init_hs(void);
void setup_surface(int id);
-
- void register_surfpid(pid_t surf_pid);
- void unregister_surfpid(pid_t surf_pid);
- pid_t find_surfpid_by_rid(pid_t app_pid);
};
#endif // RUNXDG_HPP