summaryrefslogtreecommitdiff
path: root/NativeLauncher
diff options
context:
space:
mode:
Diffstat (limited to 'NativeLauncher')
-rw-r--r--NativeLauncher/CMakeLists.txt15
-rw-r--r--NativeLauncher/inc/launcher.h27
-rw-r--r--NativeLauncher/src/dotnet/base64.cc94
-rw-r--r--NativeLauncher/src/dotnet/base64.h11
-rw-r--r--NativeLauncher/src/dotnet/dotnet_launcher.cc162
-rw-r--r--NativeLauncher/src/dotnet/dotnet_launcher.h18
-rw-r--r--NativeLauncher/src/launcher.cc201
-rw-r--r--NativeLauncher/src/main.cc108
-rw-r--r--NativeLauncher/src/mono/mono_launcher.cc213
-rw-r--r--NativeLauncher/src/mono/mono_launcher.h78
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