Remove unnecessary command name changing code (#284)
[platform/core/dotnet/launcher.git] / NativeLauncher / launcher / exec / loader.cc
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "core_runtime.h"
18 #include "utils.h"
19 #include "log.h"
20
21 #include <cstdio>
22 #include <vector>
23 #include <memory>
24
25 #include <Ecore.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <sys/prctl.h>
29
30 #include <launchpad.h>
31 #include <aul.h>
32
33 using tizen::runtime::dotnetcore::CoreRuntime;
34
35 static const char* KEY_APP_TYPE = "--appType";
36 static const char* KEY_TIZEN_UIFW = "TIZEN_UIFW";
37
38 static Ecore_Fd_Handler *__fd_handler;
39 static loader_receiver_cb __receiver;
40
41 // To precreate window(EFL/DALI), argc and argv should be passed.
42 // But, create callback of loader doesnot pass that to parameter.
43 // So, store argc and argv and use that to precreation.
44 // If window precreation code moves to managed, removed below code.
45 static int __argc;
46 static char **__argv;
47
48 typedef struct AppInfo {
49         std::string root;
50         std::string app_path;
51         std::string appid;
52         std::string pkgid;
53 } AppInfo;
54 static AppInfo __appInfo;
55
56
57 //################## Code for running event loop for loader ####################
58
59 static Eina_Bool __process_fd_handler(void *data, Ecore_Fd_Handler *handler)
60 {
61         int fd;
62
63         fd = ecore_main_fd_handler_fd_get(handler);
64         if (fd == -1) {
65                 _ERR("[candidate] ECORE_FD_GET");
66                 exit(-1);
67         }
68
69         if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
70                 if (__receiver)
71                         __receiver(fd);
72         } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
73                 _ERR("[candidate] ECORE_FD_ERROR");
74                 close(fd);
75                 exit(-1);
76         }
77
78         return ECORE_CALLBACK_CANCEL;
79 }
80
81 static void __adapter_loop_begin(void *user_data)
82 {
83         ecore_main_loop_begin();
84 }
85
86 static void __adapter_loop_quit(void *user_data)
87 {
88         ecore_main_loop_quit();
89 }
90
91 static void __adapter_add_fd(void *user_data, int fd,
92                 loader_receiver_cb receiver)
93 {
94         __fd_handler = ecore_main_fd_handler_add(fd,
95                         static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
96                         __process_fd_handler, NULL, NULL, NULL);
97
98         if (__fd_handler == NULL) {
99                 _ERR("fd_handler is NULL");
100                 close(fd);
101                 exit(-1);
102         }
103
104         __receiver = receiver;
105 }
106
107 static void __adapter_remove_fd(void *user_data, int fd)
108 {
109         if (__fd_handler) {
110                 ecore_main_fd_handler_del(__fd_handler);
111                 __fd_handler = NULL;
112                 __receiver = NULL;
113         }
114 }
115
116 //################## Code for managing loader life-cycle #######################
117
118 static void __loader_create_cb(bundle *extra, int type, void *user_data)
119 {
120         char *appType = NULL;
121         if (bundle_get_str(extra, KEY_APP_TYPE, &appType) != BUNDLE_ERROR_NONE) {
122                 appType = NULL;
123         }
124
125         char *uifw = NULL;
126         bundle_get_str(extra, KEY_TIZEN_UIFW, &uifw);
127         if (uifw != NULL) {
128                 setenv(KEY_TIZEN_UIFW, uifw, 1);
129                 _INFO("TIZEN_UIFW is set to %s", uifw);
130         }
131
132         // initialize CoreRuntime (launchmode, dlog redirection enable, root path NULL)
133         if (CoreRuntime::initialize(appType ? appType : "dotnet", LaunchMode::loader) != 0) {
134                 _ERR("Failed to initialized");
135         } else {
136                 _INFO("Success to initialized");
137         }
138 }
139
140 static int __loader_launch_cb(int argc, char **argv, const char *app_path,
141                 const char *appid, const char *pkgid, const char *pkg_type,
142                 void *user_data)
143 {
144         const char* root_path = aul_get_app_root_path();
145         if (root_path != NULL) {
146                 __appInfo.root = root_path;
147         }
148
149         __appInfo.app_path = app_path;
150         __appInfo.appid = appid;
151         __appInfo.pkgid = pkgid;
152
153         return 0;
154 }
155
156 static int __loader_terminate_cb(int argc, char **argv, void *user_data)
157 {
158         _INFO("launch request with app path : %s", __appInfo.app_path.c_str());
159
160         // The launchpad pass the name of exe file to the first argument.
161         // For the C# spec, we have to skip this first argument.
162         if (CoreRuntime::launch(__appInfo.appid.c_str(), __appInfo.root.c_str(),
163                                                 __appInfo.app_path.c_str(), argc - 1, argv + 1)) {
164                 _ERR("Failed to launch");
165                 return -1;
166         }
167
168         return 0;
169 }
170
171 //################## Main Code #################################################
172
173 extern "C" int realMain(int argc, char *argv[])
174 {
175         _INFO("##### Run in candidate mode #####");
176
177         // change cmdline from dotnet-hydra-loader to dotnet-loader
178         if (strcmp(argv[0], "/usr/bin/dotnet-hydra-loader") == 0) {
179                 memset(argv[0], '\0', strlen("/usr/bin/dotnet-hydra-loader"));
180                 snprintf(argv[0], strlen("/usr/bin/dotnet-loader") + 1,
181                                                 "/usr/bin/dotnet-loader");
182         }
183
184         loader_lifecycle_callback_s callbacks = {
185                 .create = __loader_create_cb,
186                 .launch = __loader_launch_cb,
187                 .terminate = __loader_terminate_cb
188         };
189
190         loader_adapter_s adapter = {
191                 .loop_begin = __adapter_loop_begin,
192                 .loop_quit = __adapter_loop_quit,
193                 .add_fd = __adapter_add_fd,
194                 .remove_fd = __adapter_remove_fd
195         };
196
197         int ret = launchpad_loader_main(argc, argv, &callbacks, &adapter, NULL);
198
199         CoreRuntime::finalize();
200
201         return ret;
202 }
203
204 int main(int argc, char *argv[])
205 {
206         __argc = argc;
207         __argv = argv;
208
209         return realMain(argc, argv);
210 }