Modify tizen coding style
[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                         launcher(nullptr),
54                         __isLaunched(false)
55                 { }
56                 void loaderMain(int argc, char* argv[]) override;
57
58                 std::map<int, FdHandler> handlers;
59
60         private:
61                 AppInfo appInfo;
62                 loader_lifecycle_callback_s callbacks;
63                 loader_adapter_s adapter;
64                 LauncherInterface* launcher;
65                 bool __isLaunched;
66                 std::string __launchPath;
67 };
68
69 LaunchpadAdapterImpl LaunchpadImpl;
70 LaunchpadAdapter& Launchpad = LaunchpadImpl;
71
72 #define WITH_SELF(data) \
73         LaunchpadAdapterImpl* self = static_cast<LaunchpadAdapterImpl*>(data); \
74         if (self == nullptr) \
75                 _ERR("No LaunchpadImplData"); \
76         else
77
78 static Eina_Bool fdHandler(void *data, Ecore_Fd_Handler* handler)
79 {
80         WITH_SELF(data) {
81                 int fd = ecore_main_fd_handler_fd_get(handler);
82                 if (fd == -1) {
83                         _ERR("Failed to get the Ecore FD");
84                         exit(-1);
85                 }
86
87                 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) {
88                         if (self->handlers.find(fd) != self->handlers.end())
89                                 self->handlers[fd].receiver(fd);
90                 } else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) {
91                         _ERR("Ecore FD Handler Have Error");
92                         close(fd);
93                         exit(-1);
94                 }
95         }
96
97         return ECORE_CALLBACK_CANCEL;
98 }
99
100 static void fdAdd(void *data, int fd, loader_receiver_cb receiver)
101 {
102         Ecore_Fd_Handler* handler = ecore_main_fd_handler_add(fd,
103                         static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
104                         fdHandler, data, nullptr, nullptr);
105         if (handler == nullptr) {
106                 _ERR("Failed to add a FD handler to ecore main loop");
107                 close(fd);
108                 exit(-1);
109         } WITH_SELF(data) {
110                 self->handlers[fd] = {handler, receiver};
111         }
112 }
113
114 static void fdRemove(void *data, int fd)
115 {
116         WITH_SELF(data) {
117                 if (self->handlers.find(fd) != self->handlers.end()) {
118                         Ecore_Fd_Handler* handler = self->handlers[fd].handler;
119                         ecore_main_fd_handler_del(handler);
120                         self->handlers.erase(fd);
121                 }
122         }
123 }
124
125 static void preloadLibsAndWindow(bundle *extra, int type, void *userData)
126 {
127         int elmInitCnt = 0;
128         const char **soArray;
129         int len = 0;
130         int i;
131         void *handle = NULL;
132
133         // Preload native libraries
134         if (extra == NULL) {
135                 _DBG("No extra data");
136                 return;
137         }
138
139         soArray = bundle_get_str_array(extra, "preload", &len);
140
141         if (!soArray)
142                 return;
143
144         for (i = 0; i < len; i++) {
145                 handle = dlopen(soArray[i], RTLD_NOW);
146                 _DBG("preload %s# - handle : %x", soArray[i], handle);
147         }
148
149         // Precreate window
150         elmInitCnt = elm_init(__argc, __argv);
151         _DBG("[candidate] elm init, returned: %d", elmInitCnt);
152
153         elm_config_accel_preference_set("hw");
154
155         __win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC);
156         if (__win == NULL) {
157                 _DBG("[candidate] elm_win_add() failed");
158                 return;
159         }
160
161         elm_win_precreated_object_set(__win);
162 }
163
164 void LaunchpadAdapterImpl::loaderMain(int argc, char* argv[])
165 {
166         __argc = argc;
167         __argv = argv;
168         callbacks.create = [](bundle *extra, int type, void *userData) {
169                 ecore_init();
170                 preloadLibsAndWindow(extra, type, userData);
171                 WITH_SELF(userData) {
172                         if (self->onCreate != nullptr)
173                                 self->onCreate();
174                 }
175         };
176         callbacks.launch = [](int argc, char** argv, const char* appPath,
177                                                 const char* appId, const char* pkgId,
178                                                 const char* pkgType, void* userData) -> int {
179                 WITH_SELF(userData) {
180                         self->appInfo.root = std::string(aul_get_app_root_path());
181                         self->appInfo.path = appPath;
182                         self->appInfo.id = appId;
183                         self->appInfo.pkg = pkgId;
184                         self->appInfo.type = pkgType;
185                         if (self->onLaunch != nullptr)
186                                 self->onLaunch(self->appInfo, argc, argv);
187                 }
188
189                 return 0;
190         };
191         callbacks.terminate = [](int argc, char **argv, void* userData) -> int {
192                 _DBG("Terminate!!");
193                 WITH_SELF(userData) {
194                         if (self->onTerminate != nullptr)
195                                 self->onTerminate(self->appInfo, argc, argv);
196                 }
197                 return 0;
198         };
199
200         adapter.loop_begin = [](void *data) {
201                 ecore_main_loop_begin();
202         };
203
204         adapter.loop_quit = [](void *data) {
205                 ecore_main_loop_quit();
206         };
207         adapter.add_fd = fdAdd;
208         adapter.remove_fd = fdRemove;
209
210         _DBG("launchpad_loader_main is start");
211         int r = launchpad_loader_main(argc, argv, &(this->callbacks), &(this->adapter), this);
212         _DBG("launchpad_loader_main is finished with [%d]", r);
213 }
214
215 #undef WITH_SELF
216
217 }  // namespace runtime
218 }  // namespace tizen