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() :
53 int loaderMain(int argc, char* argv[]) override;
55 std::map<int, FdHandler> handlers;
59 loader_lifecycle_callback_s callbacks;
60 hydra_lifecycle_callback_s hydraCallbacks;
61 loader_adapter_s adapter;
63 std::string __launchPath;
66 LaunchpadAdapterImpl LaunchpadImpl;
67 LaunchpadAdapter& Launchpad = LaunchpadImpl;
69 #define WITH_SELF(data) \
70 LaunchpadAdapterImpl* self = static_cast<LaunchpadAdapterImpl*>(data); \
71 if (self == nullptr) \
72 _ERR("No LaunchpadImplData"); \
75 static Eina_Bool fdHandler(void *data, Ecore_Fd_Handler* handler)
78 int fd = ecore_main_fd_handler_fd_get(handler);
80 _ERR("Failed to get the Ecore FD");
84 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
85 if (self->handlers.find(fd) != self->handlers.end())
86 self->handlers[fd].receiver(fd);
87 } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
88 _ERR("Ecore FD Handler Have Error");
94 return ECORE_CALLBACK_RENEW;
97 static void fdAdd(void *data, int fd, loader_receiver_cb receiver)
99 Ecore_Fd_Handler* handler = ecore_main_fd_handler_add(fd,
100 static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
101 fdHandler, data, nullptr, nullptr);
102 if (handler == nullptr) {
103 _ERR("Failed to add a FD handler to ecore main loop");
107 self->handlers[fd] = {handler, receiver};
111 static void fdRemove(void *data, int fd)
114 if (self->handlers.find(fd) != self->handlers.end()) {
115 Ecore_Fd_Handler* handler = self->handlers[fd].handler;
116 ecore_main_fd_handler_del(handler);
117 self->handlers.erase(fd);
122 // To run dotnet-launcher on the headless device, remove build dependency from EFL.
123 #define ELEMENTARY_PATH "/usr/lib/libelementary.so.1"
125 typedef int (*elm_init_ptr)(int argc, char **argv);
126 typedef void (*elm_config_accel_preference_set_ptr)(const char *pref);
127 typedef void* (*elm_win_add_ptr)(void* parent, const char* name, int type);
128 typedef void (*elm_win_precreated_object_set_ptr)(void* win);
130 static void preCreateWindow(bundle *extra, int type, void *userData)
133 if (stat(ELEMENTARY_PATH, &sb) != 0) {
134 _ERR("[candidate] libelementary is not exist. skip precreation");
139 void* handle = nullptr;
140 elm_init_ptr elm_init = nullptr;
141 elm_config_accel_preference_set_ptr elm_config_accel_preference_set = nullptr;
142 elm_win_add_ptr elm_win_add = nullptr;
143 elm_win_precreated_object_set_ptr elm_win_precreated_object_set = nullptr;
145 handle = dlopen(ELEMENTARY_PATH, RTLD_NOW | RTLD_GLOBAL);
147 elm_init = (elm_init_ptr)dlsym(handle, "elm_init");
149 elmInitCnt = elm_init(__argc, __argv);
152 _ERR("[candidate] elm_init() failed");
157 elm_config_accel_preference_set = (elm_config_accel_preference_set_ptr)dlsym(handle, "elm_config_accel_preference_set");
158 if (elm_config_accel_preference_set) {
159 elm_config_accel_preference_set("hw");
162 elm_win_add = (elm_win_add_ptr)dlsym(handle, "elm_win_add");
164 // enum value of "ELM_WIN_BASIC" is 0
165 __win = elm_win_add(NULL, "package_name", 0);
167 _ERR("[candidate] elm_win_add() failed");
172 elm_win_precreated_object_set = (elm_win_precreated_object_set_ptr)dlsym(handle, "elm_win_precreated_object_set");
173 if (elm_win_precreated_object_set) {
174 elm_win_precreated_object_set(__win);
176 _INFO("elm window precreation is done");
180 int LaunchpadAdapterImpl::loaderMain(int argc, char* argv[])
184 callbacks.create = [](bundle *extra, int type, void *userData) {
186 preCreateWindow(extra, type, 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) {
241 ecore_main_loop_begin();
244 adapter.loop_quit = [](void *data) {
245 ecore_main_loop_quit();
247 adapter.add_fd = fdAdd;
248 adapter.remove_fd = fdRemove;
250 _INFO("launchpad_hydra_main is start");
251 int r = launchpad_hydra_main(argc, argv, &(this->hydraCallbacks),
252 &(this->callbacks), &(this->adapter), this);
253 _INFO("launchpad_hydra_main is finished with [%d]", r);
260 } // namespace runtime