bug-fix: do not pre-create bg and conformant.
[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 {
40   Ecore_Fd_Handler *handler;
41   loader_receiver_cb receiver;
42 };
43
44 static int __argc;
45 static char **__argv;
46 static Evas_Object *__win;
47 static Evas_Object *__bg;
48 static Evas_Object *__conform;
49
50 class LaunchpadAdapterImpl : public LaunchpadAdapter
51 {
52   public:
53     LaunchpadAdapterImpl() : isLaunched(false) { }
54     void LoaderMain(int argc, char* argv[]) override;
55
56     std::map<int, FdHandler> Handlers;
57
58   private:
59     AppInfo appinfo;
60     loader_lifecycle_callback_s callbacks;
61     loader_adapter_s adapter;
62     LauncherInterface* launcher;
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   { \
74     _ERR("No LaunchpadImplData"); \
75   } else
76
77 static Eina_Bool Fd_Handler(void *data, Ecore_Fd_Handler* handler)
78 {
79   WITH_SELF(data)
80   {
81     int fd = ecore_main_fd_handler_fd_get(handler);
82     if (fd == -1)
83     {
84       _ERR("Failed to get the Ecore FD");
85       exit(-1);
86     }
87
88     if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
89     {
90       if (self->Handlers.find(fd) != self->Handlers.end())
91       {
92         self->Handlers[fd].receiver(fd);
93       }
94     }
95     else if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
96     {
97       _ERR("Ecore FD Handler Have Error");
98       close(fd);
99       exit(-1);
100     }
101   }
102
103   return ECORE_CALLBACK_CANCEL;
104 }
105
106 static void Fd_Add(void *data, int fd, loader_receiver_cb receiver)
107 {
108   Ecore_Fd_Handler* handler = ecore_main_fd_handler_add(fd,
109       static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ | ECORE_FD_ERROR),
110       Fd_Handler, data, nullptr, nullptr);
111   if (handler == nullptr)
112   {
113     _ERR("Failed to add a FD handler to ecore main loop");
114     close(fd);
115     exit(-1);
116   }
117   WITH_SELF(data)
118   {
119     self->Handlers[fd] = {handler, receiver};
120   }
121 }
122
123 static void Fd_Remove(void *data, int fd)
124 {
125   WITH_SELF(data)
126   {
127     if (self->Handlers.find(fd) != self->Handlers.end())
128     {
129       Ecore_Fd_Handler* handler = self->Handlers[fd].handler;
130       ecore_main_fd_handler_del(handler);
131       self->Handlers.erase(fd);
132     }
133   }
134 }
135
136
137 static void PreloadLibsAndWindow(bundle *extra, int type, void *user_data)
138 {
139         int elm_init_cnt = 0;
140   const char **so_array;
141   int len = 0;
142   int i;
143   void *handle = NULL;
144
145   // Preload native libraries
146         if (extra == NULL) {
147                 _DBG("No extra data");
148                 return;
149         }
150
151         so_array = bundle_get_str_array(extra, "preload", &len);
152
153         if (!so_array)
154                 return;
155
156         for (i = 0; i < len; i++) {
157                 handle = dlopen(so_array[i], RTLD_NOW);
158                 _DBG("preload %s# - handle : %x\n", so_array[i], handle);
159         }
160
161   // Precreate window
162         elm_init_cnt = elm_init(__argc, __argv);
163         _DBG("[candidate] elm init, returned: %d", elm_init_cnt);
164
165   elm_config_accel_preference_set("hw");
166
167   __win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC);
168   if (__win == NULL) {
169     _DBG("[candidate] elm_win_add() failed");
170     return;
171   }
172
173   elm_win_precreated_object_set(__win);
174 }
175
176 void LaunchpadAdapterImpl::LoaderMain(int argc, char* argv[])
177 {
178   __argc = argc;
179   __argv = argv;
180   callbacks.create = [](bundle *extra, int type, void *user_data)
181   {
182     ecore_init();
183     PreloadLibsAndWindow(extra, type, user_data);
184     WITH_SELF(user_data)
185     {
186       if (self->OnCreate != nullptr)
187         self->OnCreate();
188     }
189   };
190   callbacks.launch = [](int argc, char** argv, const char* app_path,
191       const char* appid, const char* pkgid,
192       const char* pkg_type, void* user_data) -> int
193   {
194     WITH_SELF(user_data)
195     {
196       self->appinfo.root = std::string(aul_get_app_root_path());
197       self->appinfo.path = app_path;
198       self->appinfo.id = appid;
199       self->appinfo.pkg = pkgid;
200       self->appinfo.type = pkg_type;
201       if (self->OnLaunch != nullptr)
202         self->OnLaunch(self->appinfo, argc, argv);
203     }
204
205     return 0;
206   };
207   callbacks.terminate = [](int argc, char **argv, void* user_data) -> int
208   {
209     _DBG("Terminate!!");
210     WITH_SELF(user_data)
211     {
212       if (self->OnTerminate != nullptr)
213         self->OnTerminate(self->appinfo, argc, argv);
214     }
215     return 0;
216   };
217
218   adapter.loop_begin = [](void *data)
219   {
220     ecore_main_loop_begin();
221   };
222
223   adapter.loop_quit = [](void *data)
224   {
225     ecore_main_loop_quit();
226   };
227   adapter.add_fd = Fd_Add;
228   adapter.remove_fd = Fd_Remove;
229
230   _DBG("launchpad_loader_main is start");
231   int r = launchpad_loader_main(argc, argv, &(this->callbacks), &(this->adapter), this);
232   _DBG("launchpad_loader_main is finished with [%d]", r);
233 }
234
235 #undef WITH_SELF
236
237 }  // namespace runtime
238 }  // namespace tizen