diff options
Diffstat (limited to 'NativeLauncher')
-rw-r--r-- | NativeLauncher/CMakeLists.txt | 15 | ||||
-rw-r--r-- | NativeLauncher/inc/launcher.h | 27 | ||||
-rw-r--r-- | NativeLauncher/src/dotnet/base64.cc | 94 | ||||
-rw-r--r-- | NativeLauncher/src/dotnet/base64.h | 11 | ||||
-rw-r--r-- | NativeLauncher/src/dotnet/dotnet_launcher.cc | 162 | ||||
-rw-r--r-- | NativeLauncher/src/dotnet/dotnet_launcher.h | 18 | ||||
-rw-r--r-- | NativeLauncher/src/launcher.cc | 201 | ||||
-rw-r--r-- | NativeLauncher/src/main.cc | 108 | ||||
-rw-r--r-- | NativeLauncher/src/mono/mono_launcher.cc | 213 | ||||
-rw-r--r-- | NativeLauncher/src/mono/mono_launcher.h | 78 |
10 files changed, 574 insertions, 353 deletions
diff --git a/NativeLauncher/CMakeLists.txt b/NativeLauncher/CMakeLists.txt index 203ffb7..00657be 100644 --- a/NativeLauncher/CMakeLists.txt +++ b/NativeLauncher/CMakeLists.txt @@ -18,9 +18,13 @@ IF(DEFINED LAUNCHER_CONFIG_PATH) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DLAUNCHER_CONFIG_PATH=${LAUNCHER_CONFIG_PATH}") ENDIF(DEFINED LAUNCHER_CONFIG_PATH) -IF(DEFINED LAUNCHER_ASSEMBLY_PATH) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DLAUNCHER_ASSEMBLY_PATH=${LAUNCHER_ASSEMBLY_PATH}") -ENDIF(DEFINED LAUNCHER_ASSEMBLY_PATH) +IF(DEFINED CORECLR_LAUNCHER_ASSEMBLY_PATH) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DCORECLR_LAUNCHER_ASSEMBLY_PATH=${CORECLR_LAUNCHER_ASSEMBLY_PATH}") +ENDIF(DEFINED CORECLR_LAUNCHER_ASSEMBLY_PATH) + +IF(DEFINED MONO_LAUNCHER_ASSEMBLY_PATH) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DMONO_LAUNCHER_ASSEMBLY_PATH=${MONO_LAUNCHER_ASSEMBLY_PATH}") +ENDIF(DEFINED MONO_LAUNCHER_ASSEMBLY_PATH) IF(DEFINED DEVICE_API_DIR) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DDEVICE_API_DIR=${DEVICE_API_DIR}") @@ -30,7 +34,7 @@ IF(DEFINED RUNTIME_DIR) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DRUNTIME_DIR=${RUNTIME_DIR}") ENDIF(DEFINED RUNTIME_DIR) -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -pthread -std=c++11 -Wl,--no-as-needed") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -pthread -std=c++11 -Wl,--no-as-needed -ggdb") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" ) #SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE") @@ -49,10 +53,11 @@ SET(DOTNET_LAUNCHER "dotnet-launcher") SET(MONO_LAUNCHER "mono-launcher") SET(${DOTNET_LAUNCHER}_SOURCE_FILES + src/main.cc src/utils.cc src/launcher.cc src/dotnet/dotnet_launcher.cc - src/dotnet/base64.cc + src/mono/mono_launcher.cc ) ADD_EXECUTABLE(${DOTNET_LAUNCHER} ${${PROJECT_NAME}_SOURCE_FILES}) diff --git a/NativeLauncher/inc/launcher.h b/NativeLauncher/inc/launcher.h index f4309b4..399bef5 100644 --- a/NativeLauncher/inc/launcher.h +++ b/NativeLauncher/inc/launcher.h @@ -1,28 +1,37 @@ #ifndef __LAUNCHER_INTERFACE_H__ #define __LAUNCHER_INTERFACE_H__ +#include <string> +#include <functional> + namespace tizen { namespace runtime { class LauncherInterface { public: - virtual int Initialize() = 0; + virtual int Initialize(bool standalone) = 0; virtual void Dispose() = 0; virtual int RunManagedLauncher() = 0; - virtual int Launch(const char* path, int argc, char* argv[]) = 0; + virtual int Launch(const char* root, const char* path, int argc, char* argv[]) = 0; +}; + +struct AppInfo +{ + std::string root; + std::string path; + std::string id; + std::string pkg; + std::string type; }; class LaunchpadAdapter { public: - virtual void LoaderMain(LauncherInterface* launcher, int argc, char* argv[]) = 0; - virtual void WaitUtilLaunched() = 0; - - protected: - virtual void OnCreate() = 0; - virtual void OnLaunch() = 0; - virtual void OnTerminate() = 0; + virtual void LoaderMain(int argc, char* argv[]) = 0; + std::function<void()> OnCreate = nullptr; + std::function<void(const AppInfo&, int, char**)> OnLaunch = nullptr; + std::function<void(const AppInfo&, int, char**)> OnTerminate = nullptr; }; extern LaunchpadAdapter& Launchpad; diff --git a/NativeLauncher/src/dotnet/base64.cc b/NativeLauncher/src/dotnet/base64.cc deleted file mode 100644 index 3330082..0000000 --- a/NativeLauncher/src/dotnet/base64.cc +++ /dev/null @@ -1,94 +0,0 @@ -#include "base64.h" -#include <iostream> - -static const std::string base64_chars = -"ABCDEFGHIJKLMNOPQRSTUVWXYZ" -"abcdefghijklmnopqrstuvwxyz" -"0123456789+/"; - - -static inline bool is_base64(BYTE c) { - return (isalnum(c) || (c == '+') || (c == '/')); -} - -std::string base64_encode(BYTE const* buf, unsigned int bufLen) { - std::string ret; - int i = 0; - int j = 0; - BYTE char_array_3[3]; - BYTE char_array_4[4]; - - while (bufLen--) { - char_array_3[i++] = *(buf++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) - { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - } - - return ret; -} - -std::vector<BYTE> base64_decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; - int in_ = 0; - BYTE char_array_4[4], char_array_3[3]; - std::vector<BYTE> ret; - - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; in_++; - if (i ==4) { - for (i = 0; i <4; i++) - char_array_4[i] = base64_chars.find(char_array_4[i]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (i = 0; (i < 3); i++) - ret.push_back(char_array_3[i]); - i = 0; - } - } - - if (i) { - for (j = i; j <4; j++) - char_array_4[j] = 0; - - for (j = 0; j <4; j++) - char_array_4[j] = base64_chars.find(char_array_4[j]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); - } - - return ret; -} diff --git a/NativeLauncher/src/dotnet/base64.h b/NativeLauncher/src/dotnet/base64.h deleted file mode 100644 index 1a6b6ba..0000000 --- a/NativeLauncher/src/dotnet/base64.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _BASE64_H_ -#define _BASE64_H_ - -#include <vector> -#include <string> -typedef unsigned char BYTE; - -std::string base64_encode(BYTE const* buf, unsigned int bufLen); -std::vector<BYTE> base64_decode(std::string const&); - -#endif diff --git a/NativeLauncher/src/dotnet/dotnet_launcher.cc b/NativeLauncher/src/dotnet/dotnet_launcher.cc index 4942710..62738a3 100644 --- a/NativeLauncher/src/dotnet/dotnet_launcher.cc +++ b/NativeLauncher/src/dotnet/dotnet_launcher.cc @@ -3,7 +3,6 @@ #include <string> #include <fstream> -#include <thread> #include <vector> #include "utils.h" @@ -15,43 +14,12 @@ namespace tizen { namespace runtime { namespace dotnetcore { - -void CoreRuntime::SetStandaloneExe(const char* exePath, int argc, char* argv[]) -{ - if (exePath == nullptr) - { - _ERR("executable path is null"); - return; - } - - if (FileNotExist(exePath)) - { - _ERR("File not exist : %s", exePath); - return; - } - - isLaunched = true; - LaunchParam.path = exePath; - LaunchParam.argc = argc; - LaunchParam.argv = argv; - - const char *_deviceapi_directory = getenv("DeviceAPIDirectory"); - const char *_runtime_directory = getenv("RuntimeDirectory"); - const char *_launcher_assembly = getenv("LauncherAssembly"); - if (_deviceapi_directory != nullptr) - DeviceAPIDirectory = _deviceapi_directory; - if (_runtime_directory != nullptr) - RuntimeDirectory = _runtime_directory; - if (_launcher_assembly != nullptr) - LauncherAssembly = _launcher_assembly; -} - CoreRuntime::CoreRuntime() : coreclrLib(nullptr), hostHandle(nullptr), domainId(-1), + PreparedFunction(nullptr), LaunchFunction(nullptr), - isLaunched(false), InitializeClr(nullptr), ExecuteAssembly(nullptr), Shutdown(nullptr), @@ -66,8 +34,8 @@ CoreRuntime::CoreRuntime() : #ifdef RUNTIME_DIR RuntimeDirectory = __STR(RUNTIME_DIR); #endif -#ifdef LAUNCHER_ASSEMBLY_PATH - LauncherAssembly = __STR(LAUNCHER_ASSEMBLY_PATH); +#ifdef CORECLR_LAUNCHER_ASSEMBLY_PATH + LauncherAssembly = __STR(CORECLR_LAUNCHER_ASSEMBLY_PATH); #endif #undef __STR @@ -81,9 +49,22 @@ CoreRuntime::~CoreRuntime() Dispose(); } -int CoreRuntime::Initialize() +int CoreRuntime::Initialize(bool standalone) { + if (standalone) + { + const char *_deviceapi_directory = getenv("DeviceAPIDirectory"); + const char *_runtime_directory = getenv("RuntimeDirectory"); + const char *_launcher_assembly = getenv("LauncherAssembly"); + if (_deviceapi_directory != nullptr) + DeviceAPIDirectory = _deviceapi_directory; + if (_runtime_directory != nullptr) + RuntimeDirectory = _runtime_directory; + if (_launcher_assembly != nullptr) + LauncherAssembly = _launcher_assembly; + } + if (DeviceAPIDirectory.empty()) { _ERR("Empty Device API Directory"); @@ -190,7 +171,7 @@ int CoreRuntime::RunManagedLauncher() "UseLatestBehaviorWhenTFMNotSpecified" }; -// _DBG("trusted platform assemblies : %s", propertyValues[0]); + _DBG("trusted platform assemblies : %s", propertyValues[0]); _DBG("app_path : %s", propertyValues[1]); _DBG("app_ni_path : %s", propertyValues[2]); _DBG("native dll search path : %s", propertyValues[3]); @@ -224,40 +205,34 @@ int CoreRuntime::RunManagedLauncher() _DBG("Initialize core clr success"); - void *launchFunctionDelegate; + void *preparedFunctionDelegate; st = CreateDelegate(hostHandle, domainId, - "Tizen.Runtime", - "Tizen.Runtime.AssemblyManager", - "Launch", &launchFunctionDelegate); + "Tizen.Runtime.Coreclr", + "Tizen.Runtime.Coreclr.AssemblyManager", + "Prepared", &preparedFunctionDelegate); if (st < 0) { - _ERR("Create delegate for Launch managed function is fail! (0x%08x)", st); + _ERR("Create delegate for Launch prepared function is fail (0x%08x)", st); return 1; } - LaunchFunction = reinterpret_cast<LaunchFunctionPtr>(launchFunctionDelegate); + PreparedFunction = reinterpret_cast<PreparedFunctionPtr>(preparedFunctionDelegate); - if (isLaunched) + if(PreparedFunction != nullptr) { - bool success = LaunchFunction(LaunchParam.path.c_str(), - LaunchParam.argc, LaunchParam.argv); - if (!success) - { - _ERR("Failed to Launching"); - } + PreparedFunction(); } - /* - unsigned int exitCode; - const char* argv[] = {LauncherAssembly.c_str()}; - st = ExecuteAssembly(hostHandle, domainId, - 1, argv, LauncherAssembly.c_str(), &exitCode); - _DBG("after execute coreclr"); + void *launchFunctionDelegate; + st = CreateDelegate(hostHandle, domainId, + "Tizen.Runtime.Coreclr", + "Tizen.Runtime.Coreclr.AssemblyManager", + "Launch", &launchFunctionDelegate); if (st < 0) { - _ERR("execute core clr fail! (0x%08x / %d)", st, exitCode); + _ERR("Create delegate for Launch managed function is fail! (0x%08x)", st); return 1; } - */ + LaunchFunction = reinterpret_cast<LaunchFunctionPtr>(launchFunctionDelegate); return 0; } @@ -282,67 +257,32 @@ void CoreRuntime::Dispose() _DBG("Dotnet runtime disposed"); } -int CoreRuntime::Launch(const char* path, int argc, char* argv[]) +int CoreRuntime::Launch(const char* root, const char* path, int argc, char* argv[]) { - if (LaunchFunction != nullptr) + if (path == nullptr) { - LaunchFunction(path, argc, argv); + _ERR("executable path is null"); + return 1; } - else + + if (FileNotExist(path)) { - LaunchParam.path = path; - LaunchParam.argc = argc; - LaunchParam.argv = argv; + _ERR("File not exist : %s", path); + return 1; } - isLaunched = true; - return 0; -} - -} // namespace dotnetcore -} // namespace runtime -} // namespace tizen - -static std::string StandaloneOption("--standalone"); - -#include "base64.h" - -int main(int argc, char *argv[]) -{ - int i; - bool standalone = false; - const char* standalonePath = nullptr; - - for (i=1; i<argc; i++) + bool success = false; + if (LaunchFunction != nullptr) { - if (StandaloneOption.compare(argv[i]) == 0) - { - standalone = true; - } - else + success = LaunchFunction(root, path, argc, argv); + if (!success) { - if (standalonePath == nullptr) - standalonePath = argv[i]; + _ERR("Failed to launch Application %s", path); } } - - tizen::runtime::dotnetcore::CoreRuntime runtime; - if (standalone) - { - runtime.SetStandaloneExe(standalonePath, argc, argv); - } - else - { - tizen::runtime::Launchpad.LoaderMain(&runtime, argc, argv); - } - - runtime.Initialize(); - runtime.RunManagedLauncher(); - - if (!standalone) - { - tizen::runtime::Launchpad.WaitUtilLaunched(); - } - - return 0; + return success ? 0 : 1; } + +} // namespace dotnetcore +} // namespace runtime +} // namespace tizen diff --git a/NativeLauncher/src/dotnet/dotnet_launcher.h b/NativeLauncher/src/dotnet/dotnet_launcher.h index e1a86b0..92567f6 100644 --- a/NativeLauncher/src/dotnet/dotnet_launcher.h +++ b/NativeLauncher/src/dotnet/dotnet_launcher.h @@ -36,25 +36,18 @@ namespace tizen { namespace runtime { namespace dotnetcore { -typedef bool (*LaunchFunctionPtr)(const char* path, int argc, char* argv[]); - -struct LaunchParameter -{ - std::string path; - int argc; - char** argv; -}; +typedef void (*PreparedFunctionPtr)(); +typedef bool (*LaunchFunctionPtr)(const char* root, const char* path, int argc, char* argv[]); class CoreRuntime : public tizen::runtime::LauncherInterface { public: CoreRuntime(); ~CoreRuntime(); - int Initialize() override; + int Initialize(bool standalone) override; void Dispose() override; int RunManagedLauncher() override; - int Launch(const char* path, int argc, char* argv[]) override; - void SetStandaloneExe(const char* exePath, int argc, char* argv[]); + int Launch(const char* root, const char* path, int argc, char* argv[]) override; private: coreclr_initialize_ptr InitializeClr; @@ -67,9 +60,8 @@ class CoreRuntime : public tizen::runtime::LauncherInterface void* coreclrLib; void* hostHandle; unsigned int domainId; + PreparedFunctionPtr PreparedFunction; LaunchFunctionPtr LaunchFunction; - bool isLaunched; - LaunchParameter LaunchParam; }; } // dotnetcore diff --git a/NativeLauncher/src/launcher.cc b/NativeLauncher/src/launcher.cc index 518a1d9..9efd49e 100644 --- a/NativeLauncher/src/launcher.cc +++ b/NativeLauncher/src/launcher.cc @@ -2,55 +2,46 @@ #include "log.h" #include <launchpad.h> +#include <aul.h> -#include <poll.h> +#include <Ecore.h> #include <map> #include <vector> #include <functional> -#include <thread> + +#include <unistd.h> + namespace tizen { namespace runtime { struct FdHandler { - pollfd *info; - std::function<void(int)> receiver; + Ecore_Fd_Handler *handler; + loader_receiver_cb receiver; }; class LaunchpadAdapterImpl : public LaunchpadAdapter { public: LaunchpadAdapterImpl() : isLaunched(false) { } - void LoaderMain(LauncherInterface* launcher, int argc, char* argv[]) override; - void WaitUtilLaunched() override; + void LoaderMain(int argc, char* argv[]) override; - protected: - void OnCreate() override; - void OnLaunch() override; - void OnTerminate() override; + std::map<int, FdHandler> Handlers; private: + AppInfo appinfo; loader_lifecycle_callback_s callbacks; loader_adapter_s adapter; LauncherInterface* launcher; bool isLaunched; std::string launchPath; - - bool Waiting; - std::vector<pollfd> FdList; - std::map<int, FdHandler> Handlers; - - std::thread pollingThread; }; LaunchpadAdapterImpl LaunchpadImpl; LaunchpadAdapter& Launchpad = LaunchpadImpl; -void LaunchpadAdapterImpl::LoaderMain(LauncherInterface* launcher, int argc, char* argv[]) -{ - this->launcher = launcher; #define WITH_SELF(data) \ LaunchpadAdapterImpl* self = static_cast<LaunchpadAdapterImpl*>(data); \ if (self == nullptr) \ @@ -58,12 +49,75 @@ void LaunchpadAdapterImpl::LoaderMain(LauncherInterface* launcher, int argc, cha _ERR("No LaunchpadImplData"); \ } else +static Eina_Bool Fd_Handler(void *data, Ecore_Fd_Handler* handler) +{ + WITH_SELF(data) + { + int fd = ecore_main_fd_handler_fd_get(handler); + if (fd == -1) + { + _ERR("Failed to get the Ecore FD"); + exit(-1); + } + + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) + { + if (self->Handlers.find(fd) != self->Handlers.end()) + { + self->Handlers[fd].receiver(fd); + } + } + else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) + { + _ERR("Ecore FD Handler Have Error"); + close(fd); + exit(-1); + } + } + + return ECORE_CALLBACK_CANCEL; +} + +static void Fd_Add(void *data, int fd, loader_receiver_cb receiver) +{ + Ecore_Fd_Handler* handler = ecore_main_fd_handler_add(fd, + static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR), + Fd_Handler, data, nullptr, nullptr); + if (handler == nullptr) + { + _ERR("Failed to add a FD handler to ecore main loop"); + close(fd); + exit(-1); + } + WITH_SELF(data) + { + self->Handlers[fd] = {handler, receiver}; + } +} + +static void Fd_Remove(void *data, int fd) +{ + WITH_SELF(data) + { + if (self->Handlers.find(fd) != self->Handlers.end()) + { + Ecore_Fd_Handler* handler = self->Handlers[fd].handler; + ecore_main_fd_handler_del(handler); + self->Handlers.erase(fd); + } + } +} + +void LaunchpadAdapterImpl::LoaderMain(int argc, char* argv[]) +{ callbacks.create = [](bundle *extra, int type, void *user_data) { + ecore_init(); WITH_SELF(user_data) { - self->OnCreate(); + if (self->OnCreate != nullptr) + self->OnCreate(); } }; callbacks.launch = [](int argc, char** argv, const char* app_path, @@ -72,8 +126,13 @@ void LaunchpadAdapterImpl::LoaderMain(LauncherInterface* launcher, int argc, cha { WITH_SELF(user_data) { - self->OnLaunch(); - self->launchPath = std::string(app_path); + self->appinfo.root = std::string(aul_get_app_root_path()); + self->appinfo.path = app_path; + self->appinfo.id = appid; + self->appinfo.pkg = pkgid; + self->appinfo.type = pkg_type; + if (self->OnLaunch != nullptr) + self->OnLaunch(self->appinfo, argc, argv); } return 0; @@ -83,108 +142,30 @@ void LaunchpadAdapterImpl::LoaderMain(LauncherInterface* launcher, int argc, cha _DBG("Terminate!!"); WITH_SELF(user_data) { - self->OnTerminate(); - //self->launcher->Launch(self->launchPath.c_str(), argc, argv); + if (self->OnTerminate != nullptr) + self->OnTerminate(self->appinfo, argc, argv); } return 0; }; adapter.loop_begin = [](void *data) { - _DBG("start polling..."); - WITH_SELF(data) - { - self->Waiting = true; - while(self->Waiting) - { - if (poll(self->FdList.data(), self->FdList.size(), -1) < 0) - continue; - - _DBG("-----------------------------------------------------------4"); - for (auto &p : self->FdList) - { - if ( (p.revents | POLLIN) != 0) - self->Handlers[p.fd].receiver(p.fd); - } - _DBG("-----------------------------------------------------------5"); - } - } - _DBG("end polling..."); + ecore_main_loop_begin(); }; adapter.loop_quit = [](void *data) { - WITH_SELF(data) - { - self->Waiting = false; - } - }; - - adapter.add_fd = [](void *data, int fd, loader_receiver_cb receiver) - { - WITH_SELF(data) - { - pollfd info; - FdHandler handler; - - info.fd = fd; - info.events = POLLIN; - info.revents = 0; - - self->FdList.push_back(info); - handler.info = &((self->FdList).back()); - handler.receiver = receiver; - - self->Handlers[fd] = handler; - } - }; - - adapter.remove_fd = [](void *user_data, int fd) - { - WITH_SELF(user_data) - { - pollfd *info = self->Handlers[fd].info; - self->FdList.erase(self->FdList.begin() - (info - &(self->FdList.front()))); - self->Handlers.erase(fd); - } + ecore_main_loop_quit(); }; + adapter.add_fd = Fd_Add; + adapter.remove_fd = Fd_Remove; - pollingThread = std::thread([this, argc, argv]() - { - _DBG("launchpad_loader_main is start"); - int r = launchpad_loader_main(argc, argv, &(this->callbacks), &(this->adapter), this); - _DBG("launchpad_loader_main is finished with [%d]", r); - }); - //pollingThread.detach(); -} - -void LaunchpadAdapterImpl::WaitUtilLaunched() -{ - try - { - if (pollingThread.joinable()) - { - pollingThread.join(); - } - } - catch (const std::exception& ex) - { - _ERR("Exception : %s", ex.what()); - } -} - -void LaunchpadAdapterImpl::OnCreate() -{ -} - -void LaunchpadAdapterImpl::OnLaunch() -{ -} - -void LaunchpadAdapterImpl::OnTerminate() -{ + _DBG("launchpad_loader_main is start"); + int r = launchpad_loader_main(argc, argv, &(this->callbacks), &(this->adapter), this); + _DBG("launchpad_loader_main is finished with [%d]", r); } +#undef WITH_SELF } // namespace runtime } // namespace tizen diff --git a/NativeLauncher/src/main.cc b/NativeLauncher/src/main.cc new file mode 100644 index 0000000..97ff67c --- /dev/null +++ b/NativeLauncher/src/main.cc @@ -0,0 +1,108 @@ +#include "dotnet/dotnet_launcher.h" +#include "mono/mono_launcher.h" +#include "utils.h" +#include "log.h" + +#include <memory> + +#include <Ecore.h> +#include <Eina.h> + +static std::string StandaloneOption("--standalone"); + +int main(int argc, char *argv[]) +{ + int i; + bool standalone = false; + const char* standalonePath = nullptr; + + for (i=1; i<argc; i++) + { + if (StandaloneOption.compare(argv[i]) == 0) + { + standalone = true; + } + else + { + if (standalonePath == nullptr) + standalonePath = argv[i]; + } + } + + using tizen::runtime::LauncherInterface; + using tizen::runtime::Launchpad; + using tizen::runtime::AppInfo; + std::unique_ptr<LauncherInterface> runtime; + + bool useMono = !FileNotExist("/etc/.use_mono"); + + if (!useMono) + { + using tizen::runtime::dotnetcore::CoreRuntime; + std::unique_ptr<LauncherInterface> coreRuntime(new CoreRuntime()); + runtime = std::move(coreRuntime); + } + else + { + using tizen::runtime::mono::MonoRuntime; + std::unique_ptr<LauncherInterface> monoRuntime(new MonoRuntime()); + runtime = std::move(monoRuntime); + } + + if (standalone) + { + std::string base = Basename(standalonePath); + if (runtime->Initialize(true) != 0) + { + _ERR("Failed to initialize"); + return 1; + } + if (runtime->RunManagedLauncher() != 0) + { + _ERR("Failed to run managed launcher"); + return 1; + } + if (!runtime->Launch(base.c_str(), standalonePath, argc, argv)) + { + _ERR("Failed to launch"); + return 1; + } + } + else + { + Launchpad.OnCreate = [&runtime] + { + auto idle_task = [](void *data) -> Eina_Bool + { + LauncherInterface* runtime = static_cast<LauncherInterface*>(data); + if (runtime->RunManagedLauncher() != 0) + { + _ERR("Failed to run managed launcher"); + } + return ECORE_CALLBACK_CANCEL; + }; + if (runtime->Initialize(false) != 0) + { + _ERR("Failed to initialized"); + return 1; + } + ecore_idler_add(idle_task, runtime.get()); + }; + + Launchpad.OnTerminate = [&runtime](const AppInfo& info, int argc, char** argv) + { + _DBG("terminated with app path : %s", info.path.c_str()); + _DBG("appid : %s", info.id.c_str()); + _DBG("pkg : %s", info.pkg.c_str()); + _DBG("type : %s", info.type.c_str()); + + if (!runtime->Launch(info.root.c_str(), info.path.c_str(), argc, argv)) + { + _ERR("Failed to launch"); + } + }; + Launchpad.LoaderMain(argc, argv); + } + + return 0; +} diff --git a/NativeLauncher/src/mono/mono_launcher.cc b/NativeLauncher/src/mono/mono_launcher.cc new file mode 100644 index 0000000..fff1104 --- /dev/null +++ b/NativeLauncher/src/mono/mono_launcher.cc @@ -0,0 +1,213 @@ + +#include "mono_launcher.h" +#include "utils.h" +#include "log.h" + +#include <dlfcn.h> +#include <string> + +namespace tizen { +namespace runtime { +namespace mono { + +static const char* LIBMONO = "/usr/lib/libmono-2.0.so.1"; + +MonoRuntime::MonoRuntime() : + monolib(nullptr) +{ + +#define __XSTR(x) #x +#define __STR(x) __XSTR(x) + +#ifdef MONO_LAUNCHER_ASSEMBLY_PATH + launcherAssemblyPath = __STR(MONO_LAUNCHER_ASSEMBLY_PATH); +#endif + +#ifdef DEVICE_API_DIR + deviceAPIDirectory = __STR(DEVICE_API_DIR); +#endif +#ifdef RUNTIME_DIR + runtimeDirectory = __STR(RUNTIME_DIR); +#endif + +#undef __STR +#undef __XSTR +} + +MonoRuntime::~MonoRuntime() +{ + Dispose(); +} + +int MonoRuntime::Initialize(bool standalone) +{ + if (standalone) + { + const char *_deviceapi_directory = getenv("DeviceAPIDirectory"); + const char *_runtime_directory = getenv("RuntimeDirectory"); + const char *_launcher_assembly = getenv("LauncherAssembly"); + if (_deviceapi_directory != nullptr) + deviceAPIDirectory = _deviceapi_directory; + if (_runtime_directory != nullptr) + runtimeDirectory = _runtime_directory; + if (_launcher_assembly != nullptr) + launcherAssemblyPath = _launcher_assembly; + } + + if (FileNotExist(LIBMONO)) + { + _DBG("mono is not exist in %s", LIBMONO); + return 1; + } + + monolib = dlopen(LIBMONO, RTLD_LAZY); +#define MONOLIB_RETURN_IF_NOSYM(type, variable, name) \ + do { \ + variable = (type)dlsym(monolib, name); \ + if (variable == nullptr) { \ + _ERR(name " is not found in libmono"); \ + return 1; \ + }} while(0) + + MONOLIB_RETURN_IF_NOSYM(mono_set_dirs_ptr, SetDirs, "mono_set_dirs"); + MONOLIB_RETURN_IF_NOSYM(mono_set_assemblies_path_ptr, SetAssembliesPath, "mono_set_assemblies_path"); + MONOLIB_RETURN_IF_NOSYM(mono_jit_init_ptr, JitInit, "mono_jit_init"); + MONOLIB_RETURN_IF_NOSYM(mono_domain_assembly_open_ptr, DomainAssemblyOpen, "mono_domain_assembly_open"); + MONOLIB_RETURN_IF_NOSYM(mono_assembly_get_image_ptr, AssemblyGetImage, "mono_assembly_get_image"); + MONOLIB_RETURN_IF_NOSYM(mono_class_from_name_ptr, ClassFromName, "mono_class_from_name"); + MONOLIB_RETURN_IF_NOSYM(mono_runtime_invoke_ptr, RuntimeInvoke, "mono_runtime_invoke"); + MONOLIB_RETURN_IF_NOSYM(mono_class_get_method_from_name_ptr, ClassGetMethodFromName, "mono_class_get_method_from_name"); + MONOLIB_RETURN_IF_NOSYM(mono_object_to_string_ptr, ObjectToString, "mono_object_to_string"); + MONOLIB_RETURN_IF_NOSYM(mono_string_to_utf8_ptr, StringToUtf8, "mono_string_to_utf8"); + MONOLIB_RETURN_IF_NOSYM(mono_string_new_ptr, NewString, "mono_string_new"); + MONOLIB_RETURN_IF_NOSYM(mono_get_string_class_ptr, GetStringClass, "mono_get_string_class"); + MONOLIB_RETURN_IF_NOSYM(mono_array_new_ptr, ArrayNew, "mono_array_new"); + MONOLIB_RETURN_IF_NOSYM(mono_array_addr_with_size_ptr, ArrayAddrWithSize, "mono_array_addr_with_size"); + +#undef MONOLIB_RETURN_IF_NOSYM + + _DBG("libmono dlopen and dlsym success"); + + return 0; +} + +void MonoRuntime::Dispose() +{ + if (monolib != nullptr && dlclose(monolib) != 0) + { + _ERR("libmono close failed"); + } + monolib = nullptr; +} + +int MonoRuntime::RunManagedLauncher() +{ + if (FileNotExist(launcherAssemblyPath.c_str())) + { + _ERR("Launcher Assembly is not exist in %s", launcherAssemblyPath.c_str()); + return 1; + } + +// _DBG("mono_set_dirs(\"%s\", nullptr);", runtimeDirectory.c_str()); +// _DBG("mono_set_assemblies_path(\"%s\");", deviceAPIDirectory.c_str()); + +// SetDirs(runtimeDirectory.c_str(), nullptr); +/* + std::string assembliesPath = runtimeDirectory+":"+deviceAPIDirectory; + _DBG("assembliesPath : %s", assembliesPath.c_str()); + SetAssembliesPath(assembliesPath.c_str()); + */ + SetAssembliesPath(deviceAPIDirectory.c_str()); + + domain = JitInit("tizen_mono_domain"); + if (domain == nullptr) + { + _ERR("Failed to init mono jit"); + return 1; + } + + launcherAssembly = DomainAssemblyOpen(domain, launcherAssemblyPath.c_str()); + if (launcherAssembly == nullptr) + { + _ERR("Failed to Load Launcher Assembly"); + return 1; + } + + monoImage = AssemblyGetImage(launcherAssembly); + if (monoImage == nullptr) + { + _ERR("Failed to get image from launcher assembly"); + return 1; + } + + assemblyManagerClass = ClassFromName(monoImage, "Tizen.Runtime.Mono", "AssemblyManager"); + if (assemblyManagerClass == nullptr) + { + _ERR("Failed to get AssemblyManager class in namespace Tizen.Runtime.Mono from launcher image"); + return 1; + } + + prepareLaunch = ClassGetMethodFromName(assemblyManagerClass, "Prepared", 0); + if (prepareLaunch == nullptr) + { + _ERR("Failed to get Prepared() method from Tizen.Runtime.Mono.AssemblyManager"); + return 1; + } + MonoObject* exception = nullptr; + RuntimeInvoke(prepareLaunch, nullptr, nullptr, &exception); + if (exception != nullptr) + { + MonoString * exceptionMsg = ObjectToString(exception, nullptr); + char* cstringMsg = StringToUtf8(exceptionMsg); + _ERR("Failed to invoke method in runtime"); + _ERR("%s", cstringMsg); + free(cstringMsg); + return 1; + } + + launch = ClassGetMethodFromName(assemblyManagerClass, "Launch", 4); + + return 0; +} + +#define ArrayAddr(array,type,index) ((type*)(void*) ArrayAddrWithSize (array, sizeof (type), index)) +#define ArraySet(array,type,index,value) \ + do { \ + type *__p = (type *) ArrayAddr ((array), type, (index)); \ + *__p = (value); \ + } while (0) + +int MonoRuntime::Launch(const char* root, const char* path, int argc, char* argv[]) +{ + MonoString *rootMonoString = NewString(domain, root); + MonoString *pathMonoString = NewString(domain, path); + MonoArray *argvMonoArray = ArrayNew(domain, GetStringClass(), argc); + for (int i=0; i<argc; i++) + { + MonoString *arg = NewString(domain, argv[i]); + ArraySet(argvMonoArray, MonoString*, i, arg); + } + + void **args = new void*[argc+2]; + args[0] = rootMonoString; + args[1] = pathMonoString; + args[2] = &argc; + args[3] = argvMonoArray; + + MonoObject* exception = nullptr; + RuntimeInvoke(launch, nullptr, args, &exception); + if (exception != nullptr) + { + MonoString * exceptionMsg = ObjectToString(exception, nullptr); + char* cstringMsg = StringToUtf8(exceptionMsg); + _ERR("Failed to invoke launch method in runtime"); + _ERR("%s", cstringMsg); + free(cstringMsg); + return 1; + } + return 0; +} + +} // namespace dotnetcore +} // namespace runtime +} // namespace mono diff --git a/NativeLauncher/src/mono/mono_launcher.h b/NativeLauncher/src/mono/mono_launcher.h new file mode 100644 index 0000000..8aa5a4b --- /dev/null +++ b/NativeLauncher/src/mono/mono_launcher.h @@ -0,0 +1,78 @@ +#include "launcher.h" + +extern "C" +{ + typedef struct _MonoDomain MonoDomain; + typedef struct _NonoAssembly MonoAssembly; + typedef struct _MonoImage MonoImage; + typedef struct _MonoClass MonoClass; + typedef struct _MonoObject MonoObject; + typedef struct _MonoMethod MonoMethod; + typedef struct _MonoString MonoString; + typedef struct _MonoArray MonoArray; + + typedef void (*mono_set_dirs_ptr) (const char *, const char *); + typedef void (*mono_set_assemblies_path_ptr) (const char*); + typedef MonoDomain* (*mono_jit_init_ptr) (const char *); + typedef void (*mono_config_parse_ptr) (const char *); + typedef MonoAssembly* (*mono_domain_assembly_open_ptr) (MonoDomain *, const char *); + typedef MonoImage* (*mono_assembly_get_image_ptr) (MonoAssembly *); + typedef MonoClass* (*mono_class_from_name_ptr) (MonoImage *, const char *, const char *); + typedef MonoObject* (*mono_runtime_invoke_ptr) (MonoMethod *, void *, void **, MonoObject **); + typedef MonoMethod* (*mono_class_get_method_from_name_ptr) (MonoClass *, const char *, int param_count); + typedef MonoString* (*mono_string_new_ptr) (MonoDomain *, const char *); + typedef MonoString* (*mono_object_to_string_ptr) (MonoObject *, MonoObject **); + typedef char* (*mono_string_to_utf8_ptr) (MonoString *string_obj); + + typedef MonoClass* (*mono_get_string_class_ptr) (); + typedef MonoArray* (*mono_array_new_ptr) (MonoDomain *, MonoClass *, uintptr_t); + typedef char* (*mono_array_addr_with_size_ptr) (MonoArray *, int, uintptr_t); +} + +namespace tizen { +namespace runtime { +namespace mono { + +class MonoRuntime : public tizen::runtime::LauncherInterface +{ + public: + MonoRuntime(); + ~MonoRuntime(); + int Initialize(bool standalone) override; + void Dispose() override; + int RunManagedLauncher() override; + int Launch(const char* root, const char* path, int argc, char* argv[]) override; + + private: + void* monolib; + mono_set_dirs_ptr SetDirs; + mono_set_assemblies_path_ptr SetAssembliesPath; + mono_jit_init_ptr JitInit; + mono_domain_assembly_open_ptr DomainAssemblyOpen; + mono_assembly_get_image_ptr AssemblyGetImage; + mono_class_from_name_ptr ClassFromName; + mono_runtime_invoke_ptr RuntimeInvoke; + mono_class_get_method_from_name_ptr ClassGetMethodFromName; + mono_object_to_string_ptr ObjectToString; + mono_string_to_utf8_ptr StringToUtf8; + mono_string_new_ptr NewString; + mono_get_string_class_ptr GetStringClass; + mono_array_new_ptr ArrayNew; + mono_array_addr_with_size_ptr ArrayAddrWithSize; + + MonoDomain* domain; + MonoAssembly* launcherAssembly; + MonoImage* monoImage; + MonoClass* assemblyManagerClass; + MonoMethod* prepareLaunch; + MonoMethod* launch; + + std::string launcherAssemblyPath; + std::string deviceAPIDirectory; + std::string runtimeDirectory; +}; + + +} // namespace mono +} // namespace runtime +} // namespace tizen |