b0f3e1bd0c62fb0e06bd1f45eb4eab0b9aec6f00
[platform/core/dotnet/launcher.git] / NativeLauncher / launcher / launcher.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 "launcher.h"
18 #include "log.h"
19
20 #include <launchpad.h>
21 #include <aul.h>
22
23 #include <Ecore.h>
24 #include <Elementary.h>
25 #include <bundle_internal.h>
26
27 #include <map>
28 #include <vector>
29 #include <functional>
30
31 #include <unistd.h>
32 #include <dlfcn.h>
33
34
35 namespace tizen {
36 namespace runtime {
37
38 struct FdHandler {
39         Ecore_Fd_Handler *handler;
40         loader_receiver_cb receiver;
41 };
42
43 static int __argc;
44 static char **__argv;
45 static Evas_Object *__win;
46
47 class LaunchpadAdapterImpl : public LaunchpadAdapter
48 {
49         public:
50                 LaunchpadAdapterImpl() :
51                         callbacks(),
52                         adapter(),
53                         __isLaunched(false)
54                 { }
55                 int loaderMain(int argc, char* argv[]) override;
56
57                 std::map<int, FdHandler> handlers;
58
59         private:
60                 AppInfo appInfo;
61                 loader_lifecycle_callback_s callbacks;
62                 loader_adapter_s adapter;
63                 bool __isLaunched;
64                 std::string __launchPath;
65 };
66
67 LaunchpadAdapterImpl LaunchpadImpl;
68 LaunchpadAdapter& Launchpad = LaunchpadImpl;
69
70 #define WITH_SELF(data) \
71         LaunchpadAdapterImpl* self = static_cast<LaunchpadAdapterImpl*>(data); \
72         if (self == nullptr) \
73                 _ERR("No LaunchpadImplData"); \
74         else
75
76 static Eina_Bool fdHandler(void *data, Ecore_Fd_Handler* handler)
77 {
78         WITH_SELF(data) {
79                 int fd = ecore_main_fd_handler_fd_get(handler);
80                 if (fd == -1) {
81                         _ERR("Failed to get the Ecore FD");
82                         exit(-1);
83                 }
84
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");
90                         close(fd);
91                         exit(-1);
92                 }
93         }
94
95         return ECORE_CALLBACK_CANCEL;
96 }
97
98 static void fdAdd(void *data, int fd, loader_receiver_cb receiver)
99 {
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");
105                 close(fd);
106                 exit(-1);
107         } WITH_SELF(data) {
108                 self->handlers[fd] = {handler, receiver};
109         }
110 }
111
112 static void fdRemove(void *data, int fd)
113 {
114         WITH_SELF(data) {
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);
119                 }
120         }
121 }
122
123 static void preCreateWindow(bundle *extra, int type, void *userData)
124 {
125         int elmInitCnt = 0;
126
127         // Precreate window
128         elmInitCnt = elm_init(__argc, __argv);
129         _DBG("[candidate] elm init, returned: %d", elmInitCnt);
130
131         elm_config_accel_preference_set("hw");
132
133         __win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC);
134         if (__win == NULL) {
135                 _DBG("[candidate] elm_win_add() failed");
136                 return;
137         }
138
139         elm_win_precreated_object_set(__win);
140 }
141
142 int LaunchpadAdapterImpl::loaderMain(int argc, char* argv[])
143 {
144         __argc = argc;
145         __argv = argv;
146         callbacks.create = [](bundle *extra, int type, void *userData) {
147                 ecore_init();
148                 preCreateWindow(extra, type, userData);
149                 WITH_SELF(userData) {
150                         if (self->onCreate != nullptr)
151                                 self->onCreate();
152                 }
153         };
154         callbacks.launch = [](int argc, char** argv, const char* appPath,
155                                                 const char* appId, const char* pkgId,
156                                                 const char* pkgType, void* userData) -> int {
157                 WITH_SELF(userData) {
158                         const char* appRootPath = aul_get_app_root_path();
159                         if (appRootPath != nullptr) {
160                                 self->appInfo.root = std::string(appRootPath);
161                         }
162                         self->appInfo.path = appPath;
163                         self->appInfo.id = appId;
164                         self->appInfo.pkg = pkgId;
165                         self->appInfo.type = pkgType;
166                         if (self->onLaunch != nullptr)
167                                 self->onLaunch(self->appInfo, argc, argv);
168                 }
169
170                 return 0;
171         };
172         callbacks.terminate = [](int argc, char **argv, void* userData) -> int {
173                 WITH_SELF(userData) {
174                         if (self->onTerminate != nullptr)
175                                 self->onTerminate(self->appInfo, argc, argv);
176                 }
177                 return 0;
178         };
179
180         adapter.loop_begin = [](void *data) {
181                 ecore_main_loop_begin();
182         };
183
184         adapter.loop_quit = [](void *data) {
185                 ecore_main_loop_quit();
186         };
187         adapter.add_fd = fdAdd;
188         adapter.remove_fd = fdRemove;
189
190         _DBG("launchpad_loader_main is start");
191         int r = launchpad_loader_main(argc, argv, &(this->callbacks), &(this->adapter), this);
192         _DBG("launchpad_loader_main is finished with [%d]", r);
193
194         return r;
195 }
196
197 #undef WITH_SELF
198
199 }  // namespace runtime
200 }  // namespace tizen