From cfb8bd8ca319adefe6001b823361acaf2fc1c32a Mon Sep 17 00:00:00 2001 From: Tadao Tanikawa Date: Mon, 11 Dec 2017 04:31:02 +0900 Subject: Change default method of app launch to fork/execv Change-Id: I27f4261d6427d60cf3bf522478a52fc442028d8b Signed-off-by: Tadao Tanikawa --- xdg-launcher/src/runxdg.cpp | 196 ++++++++++++++++++++++++++++++++++---------- xdg-launcher/src/runxdg.hpp | 69 ++++++++++++---- 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 #include #include +#include #include #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 +#include #include +#include #include @@ -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 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 m_pgids; // pair of + + 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 m_surfaces; // pair of - std::map m_pgids; // pair of 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 -- cgit 1.2.3-korg