Adds file logs
[platform/core/appfw/appcore-widget.git] / src / efl_base / widget_app.c
1 /*
2  * Copyright (c) 2015 - 2017 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
18 #include <stdlib.h>
19 #include <glib.h>
20
21 #include <bundle.h>
22 #include <aul.h>
23 #include <aul_widget.h>
24 #include <dlog.h>
25 #include <Elementary.h>
26 #include <widget_errno.h>
27 #include <widget_instance.h>
28
29 #include "widget_base.h"
30 #include "widget_app.h"
31 #include "widget-log.h"
32 #include "widget-private.h"
33 #include "widget_app_internal.h"
34
35 #ifdef LOG_TAG
36 #undef LOG_TAG
37 #endif
38
39 #define LOG_TAG "CAPI_WIDGET_APPLICATION"
40
41 struct instance_data {
42         Evas_Object *win;
43 };
44
45 struct app_cb_info {
46         widget_app_lifecycle_callback_s *callback;
47         void *user_data;
48 };
49
50 struct app_class_cb_info {
51         widget_instance_lifecycle_callback_s callback;
52         void *user_data;
53 };
54
55 static GList *__class_data_list;
56
57 static int __class_resize(widget_base_instance_h instance_h, int w, int h,
58                 void *class_data)
59 {
60         int ret = 0;
61         struct instance_data *data;
62         struct app_class_cb_info *callback_data =
63                         (struct app_class_cb_info *)class_data;
64
65         widget_base_class_on_resize(instance_h, w, h);
66         data = (struct instance_data *)
67                         widget_base_context_get_user_data(instance_h);
68
69         if (!data) {
70                 _E("widget_base_context_get_user_data() returns null");
71
72                 return -1;
73         }
74
75         if (data->win)
76                 evas_object_resize(data->win, w, h);
77         else
78                 _E("unable to find window");
79
80         if (callback_data && callback_data->callback.resize) {
81                 ret = callback_data->callback.resize(
82                                 (widget_context_h)instance_h,
83                                 w, h, callback_data->user_data);
84         }
85
86         return ret;
87 }
88
89 static int __class_update(widget_base_instance_h instance_h, bundle *content,
90                 int force, void *class_data)
91 {
92         int ret = 0;
93         struct app_class_cb_info *callback_data =
94                         (struct app_class_cb_info *)class_data;
95
96         widget_base_class_on_update(instance_h, content, force);
97         if (callback_data && callback_data->callback.update) {
98                 ret = callback_data->callback.update(
99                                 (widget_context_h)instance_h,
100                                 content, force, callback_data->user_data);
101         }
102
103         return ret;
104 }
105
106 static int __class_create(widget_base_instance_h instance_h, bundle *content,
107                 int w, int h, void *class_data)
108 {
109         int ret = -1;
110         struct app_class_cb_info *callback_data =
111                         (struct app_class_cb_info *)class_data;
112
113         widget_base_class_on_create(instance_h, content, w, h);
114         if (callback_data && callback_data->callback.create) {
115                 ret = callback_data->callback.create(
116                                 (widget_context_h)instance_h,
117                                 content, w, h, callback_data->user_data);
118                 aul_widget_write_log(LOG_TAG, "[%s:%d]  ret : %d",
119                         __FUNCTION__, __LINE__, ret);
120         }
121         return ret;
122 }
123
124 static int __class_destroy(widget_base_instance_h instance_h,
125                 widget_base_destroy_type_e reason, bundle *content,
126                 void *class_data)
127 {
128         int ret = 0;
129         struct instance_data *data;
130         struct app_class_cb_info *callback_data =
131                         (struct app_class_cb_info *)class_data;
132
133         if (callback_data && callback_data->callback.destroy) {
134                 ret = callback_data->callback.destroy(
135                                 (widget_context_h)instance_h,
136                                 reason, content, callback_data->user_data);
137                 aul_widget_write_log(LOG_TAG, "[%s:%d]  ret : %d",
138                         __FUNCTION__, __LINE__, ret);
139         }
140
141         data = (struct instance_data *)widget_base_context_get_user_data(instance_h);
142         if (data != NULL) {
143                 widget_base_context_set_user_data(instance_h, NULL);
144                 free(data);
145         }
146
147         widget_base_class_on_destroy(instance_h, reason, content);
148
149         return ret;
150 }
151
152 static int __class_pause(widget_base_instance_h instance_h, void *class_data)
153 {
154         int ret = 0;
155         struct app_class_cb_info *callback_data =
156                         (struct app_class_cb_info *)class_data;
157
158         widget_base_class_on_pause(instance_h);
159         if (callback_data && callback_data->callback.pause) {
160                 ret = callback_data->callback.pause(
161                                 (widget_context_h)instance_h,
162                                 callback_data->user_data);
163         }
164
165         return ret;
166 }
167
168 static int __class_resume(widget_base_instance_h instance_h, void *class_data)
169 {
170         int ret = 0;
171         struct app_class_cb_info *callback_data =
172                         (struct app_class_cb_info *)class_data;
173
174         widget_base_class_on_resume(instance_h);
175         if (callback_data && callback_data->callback.resume) {
176                 ret = callback_data->callback.resume(
177                                 (widget_context_h)instance_h,
178                                 callback_data->user_data);
179         }
180
181         return ret;
182 }
183
184 static int __widget_app_create(void *data)
185 {
186         struct app_cb_info *cb_info = (struct app_cb_info *)data;
187         widget_app_lifecycle_callback_s *callback;
188
189         widget_base_on_create();
190         if (cb_info && cb_info->callback && cb_info->callback->create) {
191                 callback = cb_info->callback;
192                 if (callback->create(cb_info->user_data) == NULL) {
193                         _D("fail to create widget");
194                         return -1;
195                 }
196                 _D("widget app is created");
197                 aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
198                 return 0;
199         }
200
201         return -1;
202 }
203
204 static int __widget_app_terminate(void *data)
205 {
206         struct app_cb_info *cb_info = (struct app_cb_info *)data;
207         widget_app_lifecycle_callback_s *callback;
208
209         if (cb_info && cb_info->callback && cb_info->callback->terminate) {
210                 callback = cb_info->callback;
211                 callback->terminate(cb_info->user_data);
212                 widget_base_on_terminate();
213                 _D("widget app is terminated");
214                 aul_widget_write_log(LOG_TAG, "[%s:%d]", __FUNCTION__, __LINE__);
215                 return 0;
216         }
217
218         widget_base_on_terminate();
219
220         return -1;
221 }
222
223 static void __widget_app_init(int argc, char **argv, void *data)
224 {
225         elm_init(argc, argv);
226 }
227
228 static void __widget_app_finish(void)
229 {
230         elm_shutdown();
231 }
232
233 static void __widget_app_run(void *data)
234 {
235         elm_run();
236 }
237
238 static void __widget_app_exit(void *data)
239 {
240         elm_exit();
241 }
242
243 EXPORT_API int widget_app_main(int argc, char **argv,
244                 widget_app_lifecycle_callback_s *callback, void *user_data)
245 {
246         widget_base_ops ops;
247         struct app_cb_info cb_info;
248         int r;
249
250         if (argc <= 0 || argv == NULL || callback == NULL)
251                 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
252                                 __FUNCTION__, NULL);
253
254         if (callback->create == NULL)
255                 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
256                                 __FUNCTION__,
257                                 "widget_app_create_cb() callback must be "
258                                 "registered");
259
260         ops.create = __widget_app_create;
261         ops.terminate = __widget_app_terminate;
262         ops.init = __widget_app_init;
263         ops.finish = __widget_app_finish;
264         ops.run = __widget_app_run;
265         ops.exit = __widget_app_exit;
266
267         cb_info.callback = callback;
268         cb_info.user_data = user_data;
269
270         r = widget_base_init(ops, argc, argv, &cb_info);
271         widget_base_fini();
272
273         if (__class_data_list) {
274                 g_list_free_full(__class_data_list, free);
275                 __class_data_list = NULL;
276         }
277
278         return r;
279 }
280
281 EXPORT_API int widget_app_exit(void)
282 {
283         return widget_base_exit();
284 }
285
286 EXPORT_API int widget_app_terminate_context(widget_context_h context)
287 {
288         return widget_base_terminate_context((widget_base_instance_h)context);
289 }
290
291 EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data)
292 {
293         return widget_base_foreach_context((widget_base_instance_cb)cb, data);
294 }
295
296 EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler,
297                                         app_event_type_e event_type,
298                                         app_event_cb callback,
299                                         void *user_data)
300 {
301         return widget_base_add_event_handler(event_handler, event_type,
302                                         callback, user_data);
303 }
304
305 EXPORT_API int widget_app_remove_event_handler(app_event_handler_h
306                                                 event_handler)
307 {
308         return widget_base_remove_event_handler(event_handler);
309 }
310
311 EXPORT_API const char *widget_app_get_id(widget_context_h context)
312 {
313         int ret;
314         char *id;
315
316         if (!context) {
317                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
318                 return NULL;
319         }
320
321         ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
322         if (ret != WIDGET_BASE_ERROR_NONE) {
323                 _E("failed to get context id"); /* LCOV_EXCL_LINE */
324                 set_last_result(ret); /* LCOV_EXCL_LINE */
325                 return NULL; /* LCOV_EXCL_LINE */
326         }
327
328         set_last_result(WIDGET_ERROR_NONE);
329         return id;
330 }
331
332 static void __win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
333 {
334         char *plug_id;
335         plug_id = evas_object_data_del(obj, "___PLUGID");
336         free(plug_id);
337 }
338
339 EXPORT_API int widget_app_get_elm_win(widget_context_h context,
340                                         Evas_Object **win)
341 {
342         Evas_Object *ret_win = NULL;
343         Ecore_Wl2_Window *wl_win;
344         struct instance_data *data;
345         char buffer[256];
346         int rots[3] = {0};
347         int win_id;
348         char *id;
349         int ret;
350
351         if (context == NULL || win == NULL)
352                 return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER,
353                                 __FUNCTION__, NULL);
354
355         ret = widget_base_context_get_id((widget_base_instance_h)context, &id);
356         if (ret != WIDGET_BASE_ERROR_NONE) {
357                 _E("failed to get context id"); /* LCOV_EXCL_LINE */
358                 goto fault; /* LCOV_EXCL_LINE */
359         }
360
361         ret_win = elm_win_add(NULL, id, ELM_WIN_BASIC);
362         if (ret_win == NULL) {
363                 _E("failed to create window"); /* LCOV_EXCL_LINE */
364                 goto fault; /* LCOV_EXCL_LINE */
365         }
366
367         elm_win_wm_rotation_preferred_rotation_set(ret_win, -1);
368         elm_win_wm_rotation_available_rotations_set(ret_win, rots, 1);
369
370         wl_win = ecore_evas_wayland2_window_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ret_win)));
371         if (wl_win == NULL) {
372                 _E("failed to get wayland window"); /* LCOV_EXCL_LINE */
373                 goto fault;
374         }
375
376         ecore_wl2_window_class_set(wl_win, id);
377         elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1");
378         widget_base_context_window_bind((widget_base_instance_h)context,        id, wl_win);
379
380         /* Set data to use in accessibility */
381         snprintf(buffer, sizeof(buffer), "%s:%d", id, getpid());
382         evas_object_data_set(ret_win, "___PLUGID", strdup(buffer));
383         evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL, __win_del_cb, NULL);
384
385         win_id = ecore_wl2_window_id_get(wl_win);
386         _D("window created: %d", win_id);
387
388         data = (struct instance_data *)widget_base_context_get_user_data(
389                         (widget_base_instance_h)context);
390         if (data == NULL) {
391                 data = calloc(1, sizeof(struct instance_data));
392                 if (data == NULL) {
393                         _E("failed to alloc instance_data"); /* LCOV_EXCL_LINE */
394                         goto fault; /* LCOV_EXCL_LINE */
395                 }
396
397                 ret = widget_base_context_set_user_data((widget_base_instance_h)context, data);
398                 if (ret != WIDGET_BASE_ERROR_NONE) {
399                         _E("fail to set extra data"); /* LCOV_EXCL_LINE */
400                         goto fault; /* LCOV_EXCL_LINE */
401                 }
402         }
403
404         data->win = ret_win;
405         *win = ret_win;
406
407         return WIDGET_ERROR_NONE;
408
409 fault:
410         if (ret_win)    /* LCOV_EXCL_LINE */
411                 evas_object_del(ret_win); /* LCOV_EXCL_LINE */
412
413         return WIDGET_ERROR_FAULT; /* LCOV_EXCL_LINE */
414 }
415
416 EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class,
417                 const char *class_id,
418                 widget_instance_lifecycle_callback_s callback, void *user_data)
419 {
420         widget_base_class cls;
421         struct app_class_cb_info *callback_data;
422         widget_class_h wc;
423
424         cls = widget_base_class_get_default();
425
426         /* override methods */
427         cls.ops.create = __class_create;
428         cls.ops.destroy = __class_destroy;
429         cls.ops.pause = __class_pause;
430         cls.ops.resume = __class_resume;
431         cls.ops.resize = __class_resize;
432         cls.ops.update = __class_update;
433
434         callback_data = calloc(1, sizeof(struct app_class_cb_info));
435         if (!callback_data) {
436                 _E("failed to calloc : %s", __FUNCTION__);
437                 set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
438                 return NULL;
439         }
440         callback_data->callback = callback;
441         callback_data->user_data = user_data;
442
443         wc = (widget_class_h)widget_base_class_add(cls, class_id,
444                         callback_data);
445
446         if (!wc) {
447                 free(callback_data);
448                 return NULL;
449         }
450
451         __class_data_list = g_list_append(__class_data_list, callback_data);
452         set_last_result(WIDGET_ERROR_NONE);
453
454         return wc;
455 }
456
457 EXPORT_API widget_class_h widget_app_class_create(
458                 widget_instance_lifecycle_callback_s callback, void *user_data)
459 {
460         char *appid;
461         widget_class_h wc;
462
463         app_get_id(&appid);
464         if (!appid) {
465                 LOGE("appid is NULL");
466                 return NULL;
467         }
468
469         wc = (widget_class_h)widget_app_class_add(NULL, appid, callback,
470                         user_data);
471         free(appid);
472
473         return wc;
474 }
475
476 EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag)
477 {
478         int ret = 0;
479
480         ret = widget_base_context_set_tag((widget_base_instance_h)context, tag);
481         if (ret != WIDGET_BASE_ERROR_NONE)
482                 return widget_app_error(ret, __FUNCTION__, NULL);
483
484         return WIDGET_ERROR_NONE;
485 }
486
487 EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag)
488 {
489         int ret = 0;
490
491         ret = widget_base_context_get_tag((widget_base_instance_h)context, tag);
492         if (ret != WIDGET_BASE_ERROR_NONE)
493                 return widget_app_error(ret, __FUNCTION__, NULL);
494
495         return WIDGET_ERROR_NONE;
496 }
497
498 EXPORT_API int widget_app_context_set_content_info(widget_context_h context,
499                 bundle *content_info)
500 {
501         int ret = 0;
502
503         ret = widget_base_context_set_content_info(
504                         (widget_base_instance_h)context, content_info);
505         if (ret != WIDGET_BASE_ERROR_NONE)
506                 return widget_app_error(ret, __FUNCTION__, NULL);
507
508         return WIDGET_ERROR_NONE;
509 }
510
511 EXPORT_API int widget_app_context_set_title(widget_context_h context,
512                 const char *title)
513 {
514         struct instance_data *data = NULL;
515         int ret;
516
517         if (!context || !title) {
518                 _E("Invalid parameter %p %p", context, title);
519                 return WIDGET_ERROR_INVALID_PARAMETER;
520         }
521
522         data = (struct instance_data *)widget_base_context_get_user_data(
523                         (widget_base_instance_h)context);
524         if (data == NULL) {
525                 data = calloc(1, sizeof(struct instance_data));
526                 if (data == NULL) {
527                         return widget_app_error(WIDGET_ERROR_FAULT,
528                                         __FUNCTION__, NULL);
529                 }
530                 ret = widget_base_context_set_user_data(context, data);
531                 if (ret != WIDGET_BASE_ERROR_NONE)
532                         widget_app_error(ret, __FUNCTION__, NULL);
533         }
534
535         if (data->win)
536                 elm_win_title_set(data->win, title);
537
538         return WIDGET_ERROR_NONE;
539 }