summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpius.lee <pius.lee@samsung.com>2016-10-10 14:12:09 +0900
committerpius.lee <pius.lee@samsung.com>2016-10-10 14:12:09 +0900
commitf15cc24b978a6650d51ccb3d62cef85ec2ad0306 (patch)
tree5909ea4cbfd762697dbefba88a625ff565632dd6
parent1d184dbef0419136311f9ca300df581721511d27 (diff)
downloadlauncher-f15cc24b978a6650d51ccb3d62cef85ec2ad0306.tar.gz
launcher-f15cc24b978a6650d51ccb3d62cef85ec2ad0306.tar.bz2
launcher-f15cc24b978a6650d51ccb3d62cef85ec2ad0306.zip
Coreclr & Mono Supported launcher and standalone
Switch launcher engine with "/etc/.use_mono" file Now can run assembly standalone with "--standalone" option Change-Id: I120053756f4d86107dfe716cf5675389b7a9760d
-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
-rw-r--r--Tizen.Runtime/Tizen.Runtime.Coreclr.csproj (renamed from Tizen.Runtime/Tizen.Runtime.csproj)10
-rw-r--r--Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs (renamed from Tizen.Runtime/Tizen.Runtime/AssemblyLoader.cs)2
-rw-r--r--Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs (renamed from Tizen.Runtime/Tizen.Runtime/AssemblyManager.cs)138
-rw-r--r--Tizen.Runtime/Tizen.Runtime.Mono.csproj75
-rw-r--r--Tizen.Runtime/Tizen.Runtime.Mono/AssemblyManager.cs153
-rw-r--r--Tizen.Runtime/Tizen.Runtime/Ini.cs139
-rw-r--r--Tizen.Runtime/Tizen.Runtime/Interop.cs28
-rw-r--r--Tizen.Runtime/Tizen.Runtime/Log.cs53
-rw-r--r--Tizen.Runtime/Tizen.Runtime/test.cs21
-rw-r--r--packaging/dotnet-launcher.spec17
20 files changed, 887 insertions, 676 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
diff --git a/Tizen.Runtime/Tizen.Runtime.csproj b/Tizen.Runtime/Tizen.Runtime.Coreclr.csproj
index a0fce08..32864ed 100644
--- a/Tizen.Runtime/Tizen.Runtime.csproj
+++ b/Tizen.Runtime/Tizen.Runtime.Coreclr.csproj
@@ -4,8 +4,8 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <OutputType>exe</OutputType>
- <AssemblyName>Tizen.Runtime</AssemblyName>
+ <OutputType>library</OutputType>
+ <AssemblyName>Tizen.Runtime.Coreclr</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug'">
@@ -34,11 +34,9 @@
</PropertyGroup>
<ItemGroup>
- <Compile Include="Tizen.Runtime/AssemblyManager.cs" />
- <Compile Include="Tizen.Runtime/AssemblyLoader.cs" />
+ <Compile Include="Tizen.Runtime.Coreclr/AssemblyManager.cs" />
+ <Compile Include="Tizen.Runtime.Coreclr/AssemblyLoader.cs" />
<Compile Include="Tizen.Runtime/Log.cs" />
- <Compile Include="Tizen.Runtime/Interop.cs" />
- <Compile Include="Tizen.Runtime/Ini.cs" />
<Compile Include="Tizen.Runtime/DefaultConfigAttribute.cs" />
</ItemGroup>
diff --git a/Tizen.Runtime/Tizen.Runtime/AssemblyLoader.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs
index 4b4a30b..2e21c7b 100644
--- a/Tizen.Runtime/Tizen.Runtime/AssemblyLoader.cs
+++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs
@@ -4,7 +4,7 @@ using System.Reflection;
using System.Runtime.Loader;
using System.Collections.Generic;
-namespace Tizen.Runtime
+namespace Tizen.Runtime.Coreclr
{
public class AssemblyLoader : AssemblyLoadContext
{
diff --git a/Tizen.Runtime/Tizen.Runtime/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs
index 6a13648..ec342d5 100644
--- a/Tizen.Runtime/Tizen.Runtime/AssemblyManager.cs
+++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs
@@ -5,28 +5,43 @@ using System.Runtime.Loader;
using System.Linq;
using System.Runtime.InteropServices;
-namespace Tizen.Runtime
+namespace Tizen.Runtime.Coreclr
{
public static class AssemblyManager
{
public static bool Launch(
+ [In] string rootPath,
[In] string path,
[In] int argc,
- [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
[In] string[] argv)
{
- Console.WriteLine($"path : {path}");
- Console.WriteLine($"argc : {argc}");
- for (int i=0; i<argc; i++)
+ ALog.Debug($"Application Launch path : {path}");
+ try
{
- Console.WriteLine($"argv[{i}] : " + argv[i]);
+ DirectoryInfo bindir = new DirectoryInfo(Path.Combine(rootPath, "bin"));
+ DirectoryInfo libdir = new DirectoryInfo(Path.Combine(rootPath, "lib"));
+ if (Directory.Exists(bindir.FullName))
+ {
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(bindir.FullName);
+ }
+ if (Directory.Exists(libdir.FullName))
+ {
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(libdir.FullName);
+ }
+ Execute(path, argv);
+ }
+ catch(Exception e)
+ {
+ ALog.Debug("Exception in Launch()");
+ PrintException(e);
+ return false;
}
- Console.WriteLine();
return true;
}
- public static int Prepared(IntPtr data)
+ public static void Prepared()
{
try
{
@@ -44,74 +59,13 @@ namespace Tizen.Runtime
if (!Initialize(preloadPath))
{
- return 1;
+ ALog.Debug($"Failed to Initialized with {preloadPath}");
}
}
catch(Exception e)
{
ALog.Debug("Exception at Preparing");
PrintException(e);
- return 1;
- }
- return 0;
- }
-
- public static int Requested(IntPtr data)
- {
- return 0;
- }
-
- public static int Executed(string path, string app_root, int argc, string[] argv, IntPtr data)
- {
- try
- {
- DirectoryInfo libdir = new DirectoryInfo(Path.Combine(app_root, "lib"));
- if (Directory.Exists(libdir.FullName))
- {
- CurrentAssemblyLoaderContext.AddSearchableDirectory(libdir.FullName);
- }
- Execute(path, argv);
- }
- catch(Exception e)
- {
- ALog.Debug("Exception at Executing");
- PrintException(e);
- return 1;
- }
-
- try
- {
- Finish();
- }
- catch(Exception e)
- {
- ALog.Debug("Exception at Finishing");
- PrintException(e);
- return 1;
- }
- return 0;
- }
-
- static Interop.PreparedCallback preparedCallback;
- static Interop.RequestedCallback requestedCallback;
- static Interop.ExecutedCallback executedCallback;
-
- public static void Main(string[] args)
- {
- try
- {
- /*
- preparedCallback = Prepared;
- requestedCallback = Requested;
- executedCallback = Executed;
- Interop.register_launching_callback(preparedCallback, requestedCallback, executedCallback, IntPtr.Zero);
- Interop.wait_for_launching(args.Length, args);
- */
- Console.WriteLine("HelloWorld!!");
- }
- catch(Exception e)
- {
- PrintException(e);
}
}
@@ -146,35 +100,6 @@ namespace Tizen.Runtime
}
}
}
-
- /*
- string LD_LIBRARY_PATH = Environment.GetEnvironmentVariable("LD_LIBRARY_PATH");
- if (!string.IsNullOrEmpty(LD_LIBRARY_PATH))
- {
- string[] dirs = LD_LIBRARY_PATH.Split(new char[]{':'}, StringSplitOptions.None);
- foreach (string dir in dirs)
- {
- DirectoryInfo d = new DirectoryInfo(dir);
- if (Directory.Exists(d.FullName))
- {
- CurrentAssemblyLoaderContext.AddSearchableDirectory(d.FullName);
- }
- }
- }
-
- DirectoryInfo libdir = new DirectoryInfo("/lib");
- if (Directory.Exists(libdir.FullName))
- {
- CurrentAssemblyLoaderContext.AddSearchableDirectory(libdir.FullName);
- }
-
- DirectoryInfo usrlibdir = new DirectoryInfo("/usr/lib");
- if (Directory.Exists(usrlibdir.FullName))
- {
- CurrentAssemblyLoaderContext.AddSearchableDirectory(usrlibdir.FullName);
- }
- */
-
}
catch (Exception e)
{
@@ -205,21 +130,6 @@ namespace Tizen.Runtime
}
}
- public static void Finish()
- {
- ALog.Debug("-------- Dll Search Dir");
- foreach (string dir in CurrentAssemblyLoaderContext.DllDirectories)
- {
- ALog.Debug(dir);
- }
-
- ALog.Debug("-------- Native Search Dir");
- foreach (string dir in CurrentAssemblyLoaderContext.NativeDirectories)
- {
- ALog.Debug(dir);
- }
- }
-
public static AssemblyLoader CurrentAssemblyLoaderContext
{
get;
diff --git a/Tizen.Runtime/Tizen.Runtime.Mono.csproj b/Tizen.Runtime/Tizen.Runtime.Mono.csproj
new file mode 100644
index 0000000..e570697
--- /dev/null
+++ b/Tizen.Runtime/Tizen.Runtime.Mono.csproj
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" InitialTargets="CheckConfig" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <OutputType>library</OutputType>
+ <AssemblyName>Tizen.Runtime.Mono</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)' == 'Debug'">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <OutputPath>bin/</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(Configuration)' == 'Release'">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin/</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ </PropertyGroup>
+
+<!-- Roslyn Not Support Assembly Signing yet.
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>Tizen.Runtime.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+-->
+
+ <PropertyGroup>
+ <DefineConstants Condition=" '$(CLOG)' != '' ">$(DefineConstants);CLOG</DefineConstants>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="Tizen.Runtime.Mono/AssemblyManager.cs" />
+ <Compile Include="Tizen.Runtime/Log.cs" />
+ <Compile Include="Tizen.Runtime/DefaultConfigAttribute.cs" />
+ </ItemGroup>
+
+ <Target Name="CheckConfig">
+ <Message Text="MSBuildProjectDirectory = $(MSBuildProjectDirectory)"/>
+ </Target>
+
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+
+ <Target Name="BeforeCompile">
+ <ItemGroup>
+ <AssemblyAttributes Include="DefaultConfigAttribute" Condition=" $(PreloadPath) != '' ">
+ <_Parameter1>PreloadPath=$(PreloadPath)</_Parameter1>
+ </AssemblyAttributes>
+ </ItemGroup>
+
+ <WriteCodeFragment AssemblyAttributes="@(AssemblyAttributes)"
+ Language="C#"
+ OutputDirectory="$(IntermediateOutputPath)"
+ OutputFile="Config.cs">
+ <Output TaskParameter="OutputFile" ItemName="Compile" />
+ </WriteCodeFragment>
+
+ </Target>
+</Project>
diff --git a/Tizen.Runtime/Tizen.Runtime.Mono/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Mono/AssemblyManager.cs
new file mode 100644
index 0000000..ec65ca6
--- /dev/null
+++ b/Tizen.Runtime/Tizen.Runtime.Mono/AssemblyManager.cs
@@ -0,0 +1,153 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using Tizen.Runtime;
+
+namespace Tizen.Runtime.Mono
+{
+ public static class AssemblyManager
+ {
+
+ private static SortedSet<string> ResolveDirectories = new SortedSet<string>();
+ private static SortedSet<string> ResolveFiles = new SortedSet<string>();
+
+ public static bool Launch(
+ [In] string rootPath,
+ [In] string path,
+ [In] int argc,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
+ [In] string[] argv)
+ {
+ ALog.Debug($"Application Launch path : {path}");
+ try
+ {
+ DirectoryInfo bindir = new DirectoryInfo(Path.Combine(rootPath, "bin"));
+ DirectoryInfo libdir = new DirectoryInfo(Path.Combine(rootPath, "lib"));
+ if (Directory.Exists(bindir.FullName))
+ {
+ ResolveDirectories.Add(bindir.FullName);
+ }
+ if (Directory.Exists(libdir.FullName))
+ {
+ ResolveDirectories.Add(libdir.FullName);
+ }
+ ResolveFiles.Add(path);
+ Execute(path, argv);
+ }
+ catch(Exception e)
+ {
+ ALog.Debug("Exception in Launch()");
+ PrintException(e);
+ return false;
+ }
+
+ return true;
+ }
+
+ static readonly string[] assemblyExtensions = {".dll", ".exe"};
+
+ public static Assembly AssemblyResolverHandler(object sender, ResolveEventArgs args)
+ {
+ // find dll name + ext in paths for resolving
+ foreach (string path in ResolveDirectories)
+ {
+ foreach (string ext in assemblyExtensions)
+ {
+ string assemblyPath = Path.Combine(path, new AssemblyName(args.Name).Name + ext);
+ if (File.Exists(assemblyPath))
+ {
+ Assembly assembly = Assembly.LoadFrom(assemblyPath);
+ return assembly;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public static void Prepared()
+ {
+ try
+ {
+ string preloadPath = "";
+ ICustomAttributeProvider assembly = typeof(AssemblyManager).GetTypeInfo().Assembly;
+ var attributes = assembly.GetCustomAttributes(typeof(DefaultConfigAttribute), false);
+ foreach (DefaultConfigAttribute dca in attributes)
+ {
+ ALog.Debug($"{dca.Key} = {dca.Value}");
+ if (dca.Key == "PreloadPath")
+ {
+ preloadPath = dca.Value;
+ }
+ }
+
+ if (!Initialize(preloadPath))
+ {
+ ALog.Debug($"Failed to Initialized with {preloadPath}");
+ }
+
+ AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolverHandler;
+ }
+ catch(Exception e)
+ {
+ ALog.Debug("Exception at Preparing");
+ PrintException(e);
+ }
+ }
+
+ private static void PrintException(Exception exception)
+ {
+ while (exception != null)
+ {
+ ALog.Debug(exception.ToString());
+ exception = exception.InnerException;
+ }
+ }
+
+ public static bool Initialize(string preloadDirectory)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(preloadDirectory))
+ {
+ Console.WriteLine($"[{preloadDirectory}]");
+ DirectoryInfo d = new DirectoryInfo(preloadDirectory);
+ if (Directory.Exists(d.FullName))
+ {
+ ResolveDirectories.Add(d.FullName);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ ALog.Debug("Exception on Initialized");
+ PrintException(e);
+ return false;
+ }
+ return true;
+ }
+
+
+ public static void Execute(string dllPath, string[] argv)
+ {
+ try
+ {
+ FileInfo f = new FileInfo(dllPath);
+ if (File.Exists(f.FullName))
+ {
+ Assembly asm = Assembly.LoadFile(f.FullName);
+ if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint");
+ asm.EntryPoint.Invoke(null, new object[]{argv});
+ }
+ }
+ catch (Exception e)
+ {
+ ALog.Debug("Exception on Execute");
+ PrintException(e);
+ }
+ }
+
+ }
+}
diff --git a/Tizen.Runtime/Tizen.Runtime/Ini.cs b/Tizen.Runtime/Tizen.Runtime/Ini.cs
deleted file mode 100644
index d5c2544..0000000
--- a/Tizen.Runtime/Tizen.Runtime/Ini.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Tizen.Runtime
-{
- internal class Ini
- {
- public string GlobalName = "___GLOBAL";
- public Ini(Uri path)
- {
- if (path.Scheme != "file")
- {
- throw new NotSupportedException("Only File Uri is supported now");
- }
- string absPath = path.AbsolutePath;
- Initialize();
- Contents = File.ReadAllText(absPath);
- }
-
- public Ini(string contents)
- {
- Initialize();
- Contents = contents;
- }
-
- public string Contents
- {
- get { return contents; }
-
- set
- {
- contents = value;
- ReadContents(contents);
- }
- }
-
- public Dictionary<string, string> this[string name]
- {
- get
- {
- if (groups.ContainsKey(name))
- return groups[name];
- return null;
- }
- }
-
- public override string ToString()
- {
- string str = "";
-
- if (groups.ContainsKey(GlobalName))
- {
- foreach (var kv in groups[GlobalName])
- {
- str += $"{kv.Key} = {kv.Value}" + Environment.NewLine;
- }
- }
-
- foreach (var gkv in groups)
- {
- if (gkv.Key == GlobalName) continue;
- str += $"[{gkv.Key}]" + Environment.NewLine;
- foreach (var kv in gkv.Value)
- {
- str += $"{kv.Key} = {kv.Value}" + Environment.NewLine;
- }
- }
-
- return str;
- }
-
- public Dictionary<string, string> Global
- {
- get
- {
- return groups[GlobalName];
- }
- }
-
- private void Initialize()
- {
- groups = new Dictionary<string, Dictionary<string, string> >();
- groups[GlobalName] = new Dictionary<string, string>();
- }
-
- private string Uncommont(string str)
- {
- int comment_start = str.IndexOf('#');
- return str.Substring(0, comment_start);
- }
-
- private bool GetHeader(string str, ref string groupName)
- {
- if (str.Length < 2 || str[0] != '[' || str[str.Length-1] != ']') return false;
- string expected = str.Substring(1, str.Length-2);
- groupName = expected.Trim();
- return true;
- }
-
- private void GetKeyValueFromString(string str, out string key, out string value)
- {
- int eq_pos = str.IndexOf('=');
- if (eq_pos == -1)
- {
- key = str.Trim();
- value = "";
- }
- else
- {
- key = str.Substring(0, eq_pos).Trim();
- value = str.Substring(eq_pos+1).Trim();
- }
- }
-
- private void ReadContents(string contents)
- {
- string key, value;
- string groupName = GlobalName;
- string[] lines = contents.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
-
- foreach (string line in lines)
- {
- if (string.IsNullOrWhiteSpace(line)) continue;
- if (GetHeader(line, ref groupName))
- {
- groups[groupName] = new Dictionary<string, string>();
- continue;
- }
- GetKeyValueFromString(line, out key, out value);
- groups[groupName][key] = value;
- }
- }
-
- private Dictionary<string, Dictionary<string, string> > groups;
- private string contents;
- }
-}
diff --git a/Tizen.Runtime/Tizen.Runtime/Interop.cs b/Tizen.Runtime/Tizen.Runtime/Interop.cs
deleted file mode 100644
index 52ceeac..0000000
--- a/Tizen.Runtime/Tizen.Runtime/Interop.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-internal static class Interop
-{
- public const string Launcher = "dotnet-launcher";
-
- internal delegate int PreparedCallback(IntPtr userData);
- internal delegate int RequestedCallback(IntPtr userData);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- internal delegate int ExecutedCallback(
- [In] string path,
- [In] string app_root,
- [In] int argc,
- [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
- [In] string[] argv,
- [In] IntPtr userData);
-
- [DllImport(Launcher)]
- internal static extern void register_launching_callback(
- [MarshalAs(UnmanagedType.FunctionPtr)] PreparedCallback prepared,
- [MarshalAs(UnmanagedType.FunctionPtr)] RequestedCallback requested,
- [MarshalAs(UnmanagedType.FunctionPtr)] ExecutedCallback executed, IntPtr userData);
-
- [DllImport(Launcher)]
- internal static extern void wait_for_launching(int argc, string[] argv);
-}
diff --git a/Tizen.Runtime/Tizen.Runtime/Log.cs b/Tizen.Runtime/Tizen.Runtime/Log.cs
index 064a5f3..b27a329 100644
--- a/Tizen.Runtime/Tizen.Runtime/Log.cs
+++ b/Tizen.Runtime/Tizen.Runtime/Log.cs
@@ -1,7 +1,7 @@
using System;
-#if !CLOG
-using Tizen;
-#endif
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
namespace Tizen.Runtime
{
@@ -35,21 +35,54 @@ namespace Tizen.Runtime
#endif
internal static class ALog
{
- static string TAG = "Tizen.Runtime";
+ const string Library = "libdlog.so.0";
+ const string TAG = "Tizen.Runtime";
+
+ public static void Debug(string message,
+ [CallerFilePath] string file = "",
+ [CallerMemberName] string func = "",
+ [CallerLineNumber] int line = 0)
+ {
+ Print(LogPriority.DLOG_DEBUG, TAG, message, file, func, line);
+ }
- public static void Debug(string message)
+ public static void Info(string message,
+ [CallerFilePath] string file = "",
+ [CallerMemberName] string func = "",
+ [CallerLineNumber] int line = 0)
{
- Log.Debug(TAG, message);
+ Print(LogPriority.DLOG_DEBUG, TAG, message, file, func, line);
}
- public static void Info(string message)
+ public static void Error(string message,
+ [CallerFilePath] string file = "",
+ [CallerMemberName] string func = "",
+ [CallerLineNumber] int line = 0)
{
- Log.Info(TAG, message);
+ Print(LogPriority.DLOG_DEBUG, TAG, message, file, func, line);
}
- public static void Error(string message)
+ internal enum LogPriority
{
- Log.Error(TAG, message);
+ DLOG_UNKNOWN = 0,
+ DLOG_DEFAULT,
+ DLOG_VERBOSE,
+ DLOG_DEBUG,
+ DLOG_INFO,
+ DLOG_WARN,
+ DLOG_ERROR,
+ DLOG_FATAL,
+ DLOG_SILENT,
+ DLOG_PRIO_MAX,
}
+
+ private static void Print(LogPriority priority, string tag, string message, string file, string func, int line)
+ {
+ FileInfo finfo = new FileInfo(file);
+ Print(priority, tag, "%s: %s(%d) > %s", finfo.Name, func, line, message);
+ }
+
+ [DllImportAttribute(Library, EntryPoint = "dlog_print")]
+ internal static extern int Print(LogPriority prio, string tag, string fmt, string file, string func, int line, string msg);
}
}
diff --git a/Tizen.Runtime/Tizen.Runtime/test.cs b/Tizen.Runtime/Tizen.Runtime/test.cs
deleted file mode 100644
index 1c65dbe..0000000
--- a/Tizen.Runtime/Tizen.Runtime/test.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Tizen.Runtime;
-
-public class Program
-{
- public static void Main(string[] args)
- {
- if (args.Length < 2)
- {
- ALog.Debug("Cancel..");
- return;
- }
- string preload = Environment.GetEnvironmentVariable("PRELOAD_DLLS");
- string searchable = String.Join(":", args, 1, args.Length - 1);
-
- if (AssemblyManager.Initialize(searchable, preload))
- {
- ALog.Debug("After Initialized...");
- AssemblyManager.Execute(args[0]);
- }
- }
-}
diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec
index c82b091..ee96df0 100644
--- a/packaging/dotnet-launcher.spec
+++ b/packaging/dotnet-launcher.spec
@@ -56,7 +56,8 @@ cmake \
-DCMAKE_BUILD_TYPE=%{_buildmode} \
-DDEVICE_API_DIR=%{_device_api_dir} \
-DRUNTIME_DIR=%{_runtime_dir} \
- -DLAUNCHER_ASSEMBLY_PATH=%{_bindir}/Tizen.Runtime.exe \
+ -DCORECLR_LAUNCHER_ASSEMBLY_PATH=%{_bindir}/Tizen.Runtime.Coreclr.dll \
+ -DMONO_LAUNCHER_ASSEMBLY_PATH=%{_bindir}/Tizen.Runtime.Mono.dll \
-DVERSION=%{version} \
NativeLauncher
@@ -66,15 +67,23 @@ xbuild \
/p:Configuration=%{_buildmode} \
/p:PreloadPath=%{_preload_dir} \
/p:TizenDeviceAPIPath=%{_device_api_dir} \
- Tizen.Runtime/Tizen.Runtime.csproj
+ Tizen.Runtime/Tizen.Runtime.Coreclr.csproj
+
+xbuild \
+ /p:Configuration=%{_buildmode} \
+ /p:PreloadPath=%{_preload_dir} \
+ /p:TizenDeviceAPIPath=%{_device_api_dir} \
+ Tizen.Runtime/Tizen.Runtime.Mono.csproj
%install
rm -rf %{buildroot}
%make_install
-install -p -m 644 Tizen.Runtime/bin/Tizen.Runtime.exe %{buildroot}%{_bindir}
+install -p -m 644 Tizen.Runtime/bin/Tizen.Runtime.Coreclr.dll %{buildroot}%{_bindir}
+install -p -m 644 Tizen.Runtime/bin/Tizen.Runtime.Mono.dll %{buildroot}%{_bindir}
%files
%manifest dotnet-launcher.manifest
%{_loaderdir}/dotnet.loader
%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/dotnet-launcher
-%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/Tizen.Runtime.exe
+%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/Tizen.Runtime.Coreclr.dll
+%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/Tizen.Runtime.Mono.dll