Fix build error
[platform/core/appfw/data-provider-slave.git] / src / main.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <malloc.h>
21 #include <mcheck.h>
22 #include <dlfcn.h>
23
24 #include <Elementary.h>
25
26 #include <glib.h>
27 #include <glib-object.h>
28 #include <gio/gio.h>
29 #include <json-glib/json-glib.h>
30 #include <Ecore.h>
31 #include <app.h>
32 #include <Edje.h>
33 #include <Eina.h>
34 #if defined(ENABLE_EFL_ASSIST)
35 #include <efl_assist.h>
36 #endif
37
38 #include <system_settings.h>
39
40 #include <dlog.h>
41 #include <bundle.h>
42 #include <widget_errno.h>
43 #include <widget_service.h>
44 #include <widget_service_internal.h>
45 #include <widget_provider.h>
46 #include <widget_script.h>
47 #include <widget_conf.h>
48 #include <widget/widget.h>      /* Conflict with local widget.h */
49 #include <widget/widget_internal.h>
50 #include <vconf.h>
51
52 #include "critical_log.h"
53 #include "debug.h"
54 #include "fault.h"
55 #include "update_monitor.h"
56 #include "client.h"
57 #include "util.h"
58 #include "so_handler.h"
59 #include "widget.h"
60 #include "conf.h"
61 #include "theme_loader.h"
62
63 #define WVGA_DEFAULT_SCALE 1.8f
64
65 static struct info {
66         int (*heap_monitor_initialized)(void);
67         size_t (*heap_monitor_target_usage)(const char *name);
68         int (*heap_monitor_add_target)(const char *name);
69         int (*heap_monitor_del_target)(const char *name);
70         void *heap_monitor;
71 #if defined(ENABLE_EFL_ASSIST)
72         Ea_Theme_Font_Table *table;
73 #endif
74
75         app_event_handler_h lang_changed_handler;
76         app_event_handler_h region_changed_handler;
77 } s_info = {
78         .heap_monitor_initialized = NULL,
79         .heap_monitor_target_usage = NULL,
80         .heap_monitor_add_target = NULL,
81         .heap_monitor_del_target = NULL,
82         .heap_monitor = NULL,
83 #if defined(ENABLE_EFL_ASSIST)
84         .table = NULL,
85 #endif
86         .lang_changed_handler = NULL,
87         .region_changed_handler = NULL,
88 };
89
90 #if defined(ENABLE_EFL_ASSIST)
91 static void font_changed_cb(void *user_data)
92 {
93         DbgPrint("Font change event\n");
94         widget_system_event_all(WIDGET_SYS_EVENT_FONT_CHANGED);
95 }
96 #endif
97
98 static void tts_changed_cb(keynode_t *node, void *user_data)
99 {
100         DbgPrint("TTS status is changed\n");
101         widget_system_event_all(WIDGET_SYS_EVENT_TTS_CHANGED);
102 }
103
104 static void mmc_changed_cb(keynode_t *node, void *user_data)
105 {
106         DbgPrint("MMC status is changed\n");
107         widget_system_event_all(WIDGET_SYS_EVENT_MMC_STATUS_CHANGED);
108 }
109
110 static void time_changed_cb(keynode_t *node, void *user_data)
111 {
112         DbgPrint("Time is changed\n");
113         widget_system_event_all(WIDGET_SYS_EVENT_TIME_CHANGED);
114 }
115
116 static void initialize_glib_type_system(void)
117 {
118         GType type;
119
120         type = G_TYPE_DBUS_ACTION_GROUP;
121         if (type != G_TYPE_OBJECT) {
122                 DbgPrint("initialized\n");
123         }
124         type = G_TYPE_DBUS_ANNOTATION_INFO;
125         if (type != G_TYPE_OBJECT) {
126                 DbgPrint("initialized\n");
127         }
128         type = G_TYPE_DBUS_ARG_INFO;
129         if (type != G_TYPE_OBJECT) {
130                 DbgPrint("initialized\n");
131         }
132         type = G_TYPE_DBUS_AUTH_OBSERVER;
133         if (type != G_TYPE_OBJECT) {
134                 DbgPrint("initialized\n");
135         }
136         type = G_TYPE_DBUS_CALL_FLAGS;
137         if (type != G_TYPE_OBJECT) {
138                 DbgPrint("initialized\n");
139         }
140         type = G_TYPE_DBUS_CAPABILITY_FLAGS;
141         if (type != G_TYPE_OBJECT) {
142                 DbgPrint("initialized\n");
143         }
144         type = G_TYPE_DBUS_CONNECTION;
145         if (type != G_TYPE_OBJECT) {
146                 DbgPrint("initialized\n");
147         }
148         type = G_TYPE_DBUS_CONNECTION_FLAGS;
149         if (type != G_TYPE_OBJECT) {
150                 DbgPrint("initialized\n");
151         }
152         type = G_TYPE_DBUS_ERROR;
153         if (type != G_TYPE_OBJECT) {
154                 DbgPrint("initialized\n");
155         }
156         type = G_TYPE_DBUS_INTERFACE;
157         if (type != G_TYPE_OBJECT) {
158                 DbgPrint("initialized\n");
159         }
160         type = G_TYPE_DBUS_INTERFACE_INFO;
161         if (type != G_TYPE_OBJECT) {
162                 DbgPrint("initialized\n");
163         }
164         type = G_TYPE_DBUS_INTERFACE_SKELETON;
165         if (type != G_TYPE_OBJECT) {
166                 DbgPrint("initialized\n");
167         }
168         type = G_TYPE_DBUS_INTERFACE_SKELETON_FLAGS;
169         if (type != G_TYPE_OBJECT) {
170                 DbgPrint("initialized\n");
171         }
172         type = G_TYPE_DBUS_MENU_MODEL;
173         if (type != G_TYPE_OBJECT) {
174                 DbgPrint("initialized\n");
175         }
176         type = G_TYPE_DBUS_MESSAGE;
177         if (type != G_TYPE_OBJECT) {
178                 DbgPrint("initialized\n");
179         }
180         type = G_TYPE_DBUS_MESSAGE_BYTE_ORDER;
181         if (type != G_TYPE_OBJECT) {
182                 DbgPrint("initialized\n");
183         }
184         type = G_TYPE_DBUS_MESSAGE_FLAGS;
185         if (type != G_TYPE_OBJECT) {
186                 DbgPrint("initialized\n");
187         }
188         type = G_TYPE_DBUS_MESSAGE_HEADER_FIELD;
189         if (type != G_TYPE_OBJECT) {
190                 DbgPrint("initialized\n");
191         }
192         type = G_TYPE_DBUS_MESSAGE_TYPE;
193         if (type != G_TYPE_OBJECT) {
194                 DbgPrint("initialized\n");
195         }
196         type = G_TYPE_DBUS_METHOD_INFO;
197         if (type != G_TYPE_OBJECT) {
198                 DbgPrint("initialized\n");
199         }
200         type = G_TYPE_DBUS_METHOD_INVOCATION;
201         if (type != G_TYPE_OBJECT) {
202                 DbgPrint("initialized\n");
203         }
204         type = G_TYPE_DBUS_NODE_INFO;
205         if (type != G_TYPE_OBJECT) {
206                 DbgPrint("initialized\n");
207         }
208         type = G_TYPE_DBUS_OBJECT;
209         if (type != G_TYPE_OBJECT) {
210                 DbgPrint("initialized\n");
211         }
212         type = G_TYPE_DBUS_OBJECT_MANAGER;
213         if (type != G_TYPE_OBJECT) {
214                 DbgPrint("initialized\n");
215         }
216         type = G_TYPE_DBUS_OBJECT_MANAGER_CLIENT;
217         if (type != G_TYPE_OBJECT) {
218                 DbgPrint("initialized\n");
219         }
220         type = G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS;
221         if (type != G_TYPE_OBJECT) {
222                 DbgPrint("initialized\n");
223         }
224         type = G_TYPE_DBUS_OBJECT_MANAGER_SERVER;
225         if (type != G_TYPE_OBJECT) {
226                 DbgPrint("initialized\n");
227         }
228         type = G_TYPE_DBUS_OBJECT_PROXY;
229         if (type != G_TYPE_OBJECT) {
230                 DbgPrint("initialized\n");
231         }
232         type = G_TYPE_DBUS_OBJECT_SKELETON;
233         if (type != G_TYPE_OBJECT) {
234                 DbgPrint("initialized\n");
235         }
236         type = G_TYPE_DBUS_PROPERTY_INFO;
237         if (type != G_TYPE_OBJECT) {
238                 DbgPrint("initialized\n");
239         }
240         type = G_TYPE_DBUS_PROPERTY_INFO_FLAGS;
241         if (type != G_TYPE_OBJECT) {
242                 DbgPrint("initialized\n");
243         }
244         type = G_TYPE_DBUS_PROXY;
245         if (type != G_TYPE_OBJECT) {
246                 DbgPrint("initialized\n");
247         }
248         type = G_TYPE_DBUS_PROXY_FLAGS;
249         if (type != G_TYPE_OBJECT) {
250                 DbgPrint("initialized\n");
251         }
252         type = G_TYPE_DBUS_SEND_MESSAGE_FLAGS;
253         if (type != G_TYPE_OBJECT) {
254                 DbgPrint("initialized\n");
255         }
256         type = G_TYPE_DBUS_SERVER;
257         if (type != G_TYPE_OBJECT) {
258                 DbgPrint("initialized\n");
259         }
260         type = G_TYPE_DBUS_SERVER_FLAGS;
261         if (type != G_TYPE_OBJECT) {
262                 DbgPrint("initialized\n");
263         }
264         type = G_TYPE_DBUS_SIGNAL_FLAGS;
265         if (type != G_TYPE_OBJECT) {
266                 DbgPrint("initialized\n");
267         }
268         type = G_TYPE_DBUS_SIGNAL_INFO;
269         if (type != G_TYPE_OBJECT) {
270                 DbgPrint("initialized\n");
271         }
272         type = G_TYPE_DBUS_SUBTREE_FLAGS;
273         if (type != G_TYPE_OBJECT) {
274                 DbgPrint("initialized\n");
275         }
276         type = JSON_TYPE_NODE;
277         if (type != G_TYPE_OBJECT) {
278                 DbgPrint("initialized\n");
279         }
280         type = JSON_TYPE_OBJECT;
281         if (type != G_TYPE_OBJECT) {
282                 DbgPrint("initialized\n");
283         }
284         type = JSON_TYPE_ARRAY;
285         if (type != G_TYPE_OBJECT) {
286                 DbgPrint("initialized\n");
287         }
288         type = JSON_TYPE_ARRAY;
289         if (type != G_TYPE_OBJECT) {
290                 DbgPrint("initialized\n");
291         }
292         type = JSON_TYPE_SERIALIZABLE;
293         if (type != G_TYPE_OBJECT) {
294                 DbgPrint("initialized\n");
295         }
296         type = JSON_TYPE_PARSER;
297         if (type != G_TYPE_OBJECT) {
298                 DbgPrint("initialized\n");
299         }
300         type = JSON_TYPE_GENERATOR;
301         if (type != G_TYPE_OBJECT) {
302                 DbgPrint("initialized\n");
303         }
304 }
305
306 static bool app_create(void *argv)
307 {
308         int ret;
309
310         elm_app_base_scale_set(WVGA_DEFAULT_SCALE);
311
312         widget_conf_init();
313         if (!widget_conf_is_loaded()) {
314                 ret = widget_conf_load();
315                 if (ret < 0) {
316                         DbgPrint("Configureation manager is initiated: %d\n", ret);
317                 }
318         }
319
320         critical_log_init(util_basename(((char **)argv)[0]));
321
322         /*!
323          * Touch the glib type system
324          */
325         initialize_glib_type_system();
326
327         DbgPrint("Scale factor: %lf\n", elm_config_scale_get());
328
329         if (WIDGET_CONF_COM_CORE_THREAD) {
330                 if (setenv("PROVIDER_COM_CORE_THREAD", "true", 0) < 0) {
331                         ErrPrint("setenv: %d\n", errno);
332                 }
333         } else {
334                 if (setenv("PROVIDER_COM_CORE_THREAD", "false", 0) < 0){
335                         ErrPrint("setenv: %d\n", errno);
336                 }
337         }
338
339         ret = widget_service_init();
340         if (ret < 0) {
341                 DbgPrint("Livebox service init: %d\n", ret);
342         }
343
344         /**
345          * @note
346          * Slave is not able to initiate system, before
347          * receive its name from the master
348          *
349          * So create callback doesn't do anything.
350          */
351         ret = fault_init(argv);
352         if (ret < 0) {
353                 DbgPrint("Crash recover is initiated: %d\n", ret);
354         }
355
356         ret = update_monitor_init();
357         if (ret < 0) {
358                 DbgPrint("Content update monitor is initiated: %d\n", ret);
359         }
360
361         ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, time_changed_cb, NULL);
362         if (ret < 0) {
363                 DbgPrint("System time changed event callback added: %d\n", ret);
364         }
365
366         ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, mmc_changed_cb, NULL);
367         if (ret < 0) {
368                 DbgPrint("MMC status changed event callback added: %d\n", ret);
369         }
370
371         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, tts_changed_cb, NULL);
372         if (ret < 0) {
373                 DbgPrint("TTS changed callback is added: %s\n", ret);
374         }
375
376 #if defined(ENABLE_EFL_ASSIST)
377         s_info.table = ea_theme_font_table_new("/usr/share/themes/FontInfoTable.xml");
378         if (s_info.table) {
379                 DbgPrint("FONT TABLE Prepared");
380                 ea_theme_fonts_set(s_info.table);
381         }
382         ea_theme_event_callback_add(EA_THEME_CALLBACK_TYPE_FONT, font_changed_cb, NULL);
383
384         font_changed_cb(NULL);
385         theme_loader_load(THEME_DIR);
386 #endif
387
388
389         widget_viewer_init();
390
391         return TRUE;
392 }
393
394 static void app_terminate(void *data)
395 {
396         int ret;
397
398         DbgPrint("Terminating provider\n");
399
400         widget_viewer_fini();
401
402 #if defined(ENABLE_EFL_ASSIST)
403         theme_loader_unload();
404
405         if (s_info.table) {
406                 DbgPrint("FONT TABLE Destroyed");
407                 ea_theme_font_table_free(s_info.table);
408                 s_info.table = NULL;
409         }
410
411         ea_theme_event_callback_del(EA_THEME_CALLBACK_TYPE_FONT, font_changed_cb);
412 #endif
413
414         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, tts_changed_cb);
415         if (ret < 0) {
416                 DbgPrint("TTS changed callback is added: %s\n", ret);
417         }
418
419         ret = vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, time_changed_cb);
420         if (ret < 0) {
421                 DbgPrint("Remove time changed callback: %d\n", ret);
422         }
423
424         ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, mmc_changed_cb);
425         if (ret < 0) {
426                 DbgPrint("Remove MMC status changed callback: %d\n", ret);
427         }
428
429         ret = update_monitor_fini();
430         if (ret < 0) {
431                 DbgPrint("Content update monitor is finalized: %d\n", ret);
432         }
433
434         ret = fault_fini();
435         if (ret < 0) {
436                 DbgPrint("Crash recover is finalized: %d\n", ret);
437         }
438
439         ret = client_fini();
440         if (ret < 0) {
441                 DbgPrint("client finalized: %d\n", ret); 
442         }
443
444         ret = widget_service_fini();
445         if (ret < 0) {
446                 DbgPrint("widget service fini: %d\n", ret);
447         }
448
449         critical_log_fini();
450
451         exit(0);
452         return;
453 }
454
455 static void app_pause(void *data)
456 {
457         /* Will not be invoked */
458         return;
459 }
460
461 static void app_resume(void *data)
462 {
463         /* Will not be invoked */
464         return;
465 }
466
467 static void app_region_changed(app_event_info_h event_info, void *data)
468 {
469         // char *region;
470         // app_event_get_region_format(event_info, &region);
471         widget_system_event_all(WIDGET_SYS_EVENT_REGION_CHANGED);
472 }
473
474 static void app_language_changed(app_event_info_h event_info, void *data)
475 {
476         // char *lang;
477         // app_event_get_language(event_info, &lang);
478         widget_system_event_all(WIDGET_SYS_EVENT_LANG_CHANGED);
479 }
480
481 static void app_control(app_control_h service, void *data)
482 {
483         int ret;
484         char *name;
485         char *secured;
486         char *hw_acceleration = NULL;
487         char *abi;
488         static int initialized = 0;
489
490         if (initialized) {
491                 ErrPrint("Already initialized\n");
492                 return;
493         }
494
495         ret = app_control_get_extra_data(service, WIDGET_CONF_BUNDLE_SLAVE_NAME, &name);
496         if (ret != APP_CONTROL_ERROR_NONE) {
497                 ErrPrint("Name is not valid\n");
498                 return;
499         }
500
501         ret = app_control_get_extra_data(service, WIDGET_CONF_BUNDLE_SLAVE_SECURED, &secured);
502         if (ret != APP_CONTROL_ERROR_NONE) {
503                 free(name);
504                 ErrPrint("Secured is not valid\n");
505                 return;
506         }
507
508         ret = app_control_get_extra_data(service, WIDGET_CONF_BUNDLE_SLAVE_HW_ACCELERATION, &hw_acceleration);
509         if (ret != APP_CONTROL_ERROR_NONE) {
510                 DbgPrint("Unable to get option for hw-acceleration\n");
511                 hw_acceleration = strdup("use-x11");
512                 /* Go ahead */
513         }
514
515         ret = app_control_get_extra_data(service, WIDGET_CONF_BUNDLE_SLAVE_ABI, &abi);
516         if (ret != APP_CONTROL_ERROR_NONE) {
517                 DbgPrint("Unable to get option for hw-acceleration\n");
518                 abi = strdup(WIDGET_CONF_DEFAULT_ABI);
519                 /* Go ahead */
520         }
521
522         if (!strcasecmp(secured, "true")) {
523                 /* Don't use the update timer */
524                 widget_turn_secured_on();
525         }
526
527         DbgPrint("Name assigned: %s\n", name);
528         DbgPrint("Secured: %s\n", secured);
529         DbgPrint("hw-acceleration: %s\n", hw_acceleration);
530         DbgPrint("abi: %s\n", abi);
531         ret = client_init(name, abi, hw_acceleration, widget_is_secured());
532
533         if (hw_acceleration && !strcasecmp(hw_acceleration, "use-gl")) {
534                 DbgPrint("Turn on: opengl_x11\n");
535                 elm_config_accel_preference_set("opengl");
536         }
537
538         free(name);
539         free(secured);
540         free(hw_acceleration);
541         free(abi);
542
543         initialized = 1;
544         return;
545 }
546
547 #if defined(_ENABLE_MCHECK)
548 static inline void mcheck_cb(enum mcheck_status status)
549 {
550         char *ptr;
551
552         ptr = util_get_current_module(NULL);
553
554         switch (status) {
555         case MCHECK_DISABLED:
556                 ErrPrint("[DISABLED] Heap incosistency detected: %s\n", ptr);
557                 break;
558         case MCHECK_OK:
559                 ErrPrint("[OK] Heap incosistency detected: %s\n", ptr);
560                 break;
561         case MCHECK_HEAD:
562                 ErrPrint("[HEAD] Heap incosistency detected: %s\n", ptr);
563                 break;
564         case MCHECK_TAIL:
565                 ErrPrint("[TAIL] Heap incosistency detected: %s\n", ptr);
566                 break;
567         case MCHECK_FREE:
568                 ErrPrint("[FREE] Heap incosistency detected: %s\n", ptr);
569                 break;
570         default:
571                 break;
572         }
573 }
574 #endif
575
576 #define HEAP_MONITOR_PATH "/usr/lib/libheap-monitor.so"
577 #define BIN_PATH "/usr/apps/org.tizen.data-provider-slave/bin/"
578 int main(int argc, char *argv[])
579 {
580         int ret;
581         ui_app_lifecycle_callback_s event_callback;
582
583         const char *option;
584
585         memset(argv[0], 0, strlen(argv[0]));
586         strcpy(argv[0], BIN_PATH "data-provider-slave");
587         DbgPrint("Replace argv[0] with %s\n", argv[0]);
588
589 #if defined(_ENABLE_MCHECK)
590         mcheck(mcheck_cb);
591 #endif
592         option = getenv("PROVIDER_DISABLE_CALL_OPTION");
593         if (option && !strcasecmp(option, "true")) {
594                 fault_disable_call_option();
595         }
596
597         option = getenv("PROVIDER_HEAP_MONITOR_START");
598         if (option && !strcasecmp(option, "true")) {
599                 s_info.heap_monitor = dlopen(HEAP_MONITOR_PATH, RTLD_NOW);
600                 if (s_info.heap_monitor) {
601                         s_info.heap_monitor_initialized = dlsym(s_info.heap_monitor, "heap_monitor_initialized");
602                         s_info.heap_monitor_target_usage = dlsym(s_info.heap_monitor, "heap_monitor_target_usage");
603                         s_info.heap_monitor_add_target = dlsym(s_info.heap_monitor, "heap_monitor_add_target");
604                         s_info.heap_monitor_del_target = dlsym(s_info.heap_monitor, "heap_monitor_del_target");
605                 }
606         }
607
608         if (setenv("BUFMGR_LOCK_TYPE", "once", 0) < 0) {
609                 ErrPrint("setenv: %d\n", errno);
610         }
611
612         if (setenv("BUFMGR_MAP_CACHE", "true", 0) < 0) {
613                 ErrPrint("setenv: %d\n", errno);
614         }
615
616         event_callback.create = app_create;
617         event_callback.terminate = app_terminate;
618         event_callback.pause = app_pause;
619         event_callback.resume = app_resume;
620         event_callback.app_control = app_control;
621
622         ui_app_add_event_handler(&s_info.lang_changed_handler, APP_EVENT_LANGUAGE_CHANGED, app_language_changed, argv);
623         ui_app_add_event_handler(&s_info.region_changed_handler, APP_EVENT_REGION_FORMAT_CHANGED, app_region_changed, argv);
624         // APP_EVENT_DEVICE_ORIENTATION_CHANGED
625         // APP_EVENT_LOW_MEMORY
626         // APP_EVENT_LOW_BATTERY
627
628         ret = ui_app_main(argc, argv, &event_callback, (void *)argv);
629         ErrPrint("ui_app_main: %d\n", ret);
630
631         if (s_info.heap_monitor) {
632                 if (dlclose(s_info.heap_monitor) < 0) {
633                         ErrPrint("dlclose: %d\n", errno);
634                 }
635         }
636
637         return ret;
638 }
639
640 HAPI int main_heap_monitor_is_enabled(void)
641 {
642         return s_info.heap_monitor_initialized ? s_info.heap_monitor_initialized() : 0;
643 }
644
645 HAPI size_t main_heap_monitor_target_usage(const char *name)
646 {
647         return s_info.heap_monitor_target_usage ? s_info.heap_monitor_target_usage(name) : 0;
648 }
649
650 HAPI int main_heap_monitor_add_target(const char *name)
651 {
652         return s_info.heap_monitor_add_target ? s_info.heap_monitor_add_target(name) : 0;
653 }
654
655 HAPI int main_heap_monitor_del_target(const char *name)
656 {
657         return s_info.heap_monitor_del_target ? s_info.heap_monitor_del_target(name) : 0;
658 }
659
660 HAPI void main_app_exit(void)
661 {
662         ui_app_exit();
663 }
664 /* End of a file */