2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <launchpad.h>
24 #include <bundle_internal.h>
38 Ecore_Fd_Handler *handler;
39 loader_receiver_cb receiver;
45 class LaunchpadAdapterImpl : public LaunchpadAdapter
48 LaunchpadAdapterImpl() :
54 int loaderMain(int argc, char* argv[]) override;
56 std::map<int, FdHandler> handlers;
60 loader_lifecycle_callback_s callbacks;
61 hydra_lifecycle_callback_s hydraCallbacks;
62 loader_adapter_s adapter;
64 std::string __launchPath;
67 LaunchpadAdapterImpl LaunchpadImpl;
68 LaunchpadAdapter& Launchpad = LaunchpadImpl;
70 #define WITH_SELF(data) \
71 LaunchpadAdapterImpl* self = static_cast<LaunchpadAdapterImpl*>(data); \
72 if (self == nullptr) \
73 _ERR("No LaunchpadImplData"); \
76 static Eina_Bool fdHandler(void *data, Ecore_Fd_Handler* handler)
79 int fd = ecore_main_fd_handler_fd_get(handler);
81 _ERR("Failed to get the Ecore FD");
85 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
86 if (self->handlers.find(fd) != self->handlers.end())
87 self->handlers[fd].receiver(fd);
88 } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
89 _ERR("Ecore FD Handler Have Error");
95 return ECORE_CALLBACK_RENEW;
98 static void fdAdd(void *data, int fd, loader_receiver_cb receiver)
100 Ecore_Fd_Handler* handler = ecore_main_fd_handler_add(fd,
101 static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
102 fdHandler, data, nullptr, nullptr);
103 if (handler == nullptr) {
104 _ERR("Failed to add a FD handler to ecore main loop");
108 self->handlers[fd] = {handler, receiver};
112 static void fdRemove(void *data, int fd)
115 if (self->handlers.find(fd) != self->handlers.end()) {
116 Ecore_Fd_Handler* handler = self->handlers[fd].handler;
117 ecore_main_fd_handler_del(handler);
118 self->handlers.erase(fd);
123 // To run dotnet-launcher on the headless device, remove build dependency from EFL.
124 #define ELEMENTARY_PATH "/usr/lib/libelementary.so.1"
126 typedef int (*elm_init_ptr)(int argc, char **argv);
127 typedef void (*elm_config_accel_preference_set_ptr)(const char *pref);
128 typedef void* (*elm_win_add_ptr)(void* parent, const char* name, int type);
129 typedef void (*elm_win_precreated_object_set_ptr)(void* win);
131 static void preCreateWindow()
134 if (stat(ELEMENTARY_PATH, &sb) != 0) {
135 _ERR("[candidate] libelementary is not exist. skip precreation");
140 void* handle = nullptr;
141 elm_init_ptr elm_init = nullptr;
142 elm_config_accel_preference_set_ptr elm_config_accel_preference_set = nullptr;
143 elm_win_add_ptr elm_win_add = nullptr;
144 elm_win_precreated_object_set_ptr elm_win_precreated_object_set = nullptr;
146 handle = dlopen(ELEMENTARY_PATH, RTLD_NOW | RTLD_GLOBAL);
148 elm_init = (elm_init_ptr)dlsym(handle, "elm_init");
150 elmInitCnt = elm_init(__argc, __argv);
153 _ERR("[candidate] elm_init() failed");
158 elm_config_accel_preference_set = (elm_config_accel_preference_set_ptr)dlsym(handle, "elm_config_accel_preference_set");
159 if (elm_config_accel_preference_set) {
160 elm_config_accel_preference_set("hw");
163 elm_win_add = (elm_win_add_ptr)dlsym(handle, "elm_win_add");
165 // enum value of "ELM_WIN_BASIC" is 0
166 __win = elm_win_add(NULL, "package_name", 0);
168 _ERR("[candidate] elm_win_add() failed");
173 elm_win_precreated_object_set = (elm_win_precreated_object_set_ptr)dlsym(handle, "elm_win_precreated_object_set");
174 if (elm_win_precreated_object_set) {
175 elm_win_precreated_object_set(__win);
177 _INFO("elm window precreation is done");
181 int LaunchpadAdapterImpl::loaderMain(int argc, char* argv[])
185 callbacks.create = [](bundle *extra, int type, void *userData) {
187 WITH_SELF(userData) {
188 if (self->onCreate != nullptr)
192 callbacks.launch = [](int argc, char** argv, const char* appPath,
193 const char* appId, const char* pkgId,
194 const char* pkgType, void* userData) -> int {
195 WITH_SELF(userData) {
196 const char* appRootPath = aul_get_app_root_path();
197 if (appRootPath != nullptr) {
198 self->appInfo.root = std::string(appRootPath);
200 self->appInfo.path = appPath;
201 self->appInfo.id = appId;
202 self->appInfo.pkg = pkgId;
203 self->appInfo.type = pkgType;
204 if (self->onLaunch != nullptr)
205 self->onLaunch(self->appInfo, argc, argv);
210 callbacks.terminate = [](int argc, char **argv, void* userData) -> int {
211 WITH_SELF(userData) {
212 if (self->onTerminate != nullptr)
213 self->onTerminate(self->appInfo, argc, argv);
218 // Called before initial fork
219 hydraCallbacks.precreate = [](void* userData) {
220 WITH_SELF(userData) {
221 if (self->onPreCreate != nullptr)
226 hydraCallbacks.create = [](void* userData) {
230 // Called after fork in candidate
231 hydraCallbacks.fork = [](void *userData) {
235 hydraCallbacks.terminate = [](void* userData) {
240 adapter.loop_begin = [](void *data) {
242 ecore_main_loop_begin();
245 adapter.loop_quit = [](void *data) {
246 ecore_main_loop_quit();
248 adapter.add_fd = fdAdd;
249 adapter.remove_fd = fdRemove;
251 _INFO("launchpad_hydra_main is start");
252 int r = launchpad_hydra_main(argc, argv, &(this->hydraCallbacks),
253 &(this->callbacks), &(this->adapter), this);
254 _INFO("launchpad_hydra_main is finished with [%d]", r);
261 } // namespace runtime