2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
24 #include <Elementary.h>
27 #include <glib-object.h>
29 #include <json-glib/json-glib.h>
34 #if defined(ENABLE_EFL_ASSIST)
35 #include <efl_assist.h>
38 #include <system_settings.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>
52 #include "critical_log.h"
55 #include "update_monitor.h"
58 #include "so_handler.h"
61 #include "theme_loader.h"
63 #define WVGA_DEFAULT_SCALE 1.8f
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);
71 #if defined(ENABLE_EFL_ASSIST)
72 Ea_Theme_Font_Table *table;
75 app_event_handler_h lang_changed_handler;
76 app_event_handler_h region_changed_handler;
78 .heap_monitor_initialized = NULL,
79 .heap_monitor_target_usage = NULL,
80 .heap_monitor_add_target = NULL,
81 .heap_monitor_del_target = NULL,
83 #if defined(ENABLE_EFL_ASSIST)
86 .lang_changed_handler = NULL,
87 .region_changed_handler = NULL,
90 #if defined(ENABLE_EFL_ASSIST)
91 static void font_changed_cb(void *user_data)
93 DbgPrint("Font change event\n");
94 widget_system_event_all(WIDGET_SYS_EVENT_FONT_CHANGED);
98 static void tts_changed_cb(keynode_t *node, void *user_data)
100 DbgPrint("TTS status is changed\n");
101 widget_system_event_all(WIDGET_SYS_EVENT_TTS_CHANGED);
104 static void mmc_changed_cb(keynode_t *node, void *user_data)
106 DbgPrint("MMC status is changed\n");
107 widget_system_event_all(WIDGET_SYS_EVENT_MMC_STATUS_CHANGED);
110 static void time_changed_cb(keynode_t *node, void *user_data)
112 DbgPrint("Time is changed\n");
113 widget_system_event_all(WIDGET_SYS_EVENT_TIME_CHANGED);
116 static void initialize_glib_type_system(void)
120 type = G_TYPE_DBUS_ACTION_GROUP;
121 if (type != G_TYPE_OBJECT) {
122 DbgPrint("initialized\n");
124 type = G_TYPE_DBUS_ANNOTATION_INFO;
125 if (type != G_TYPE_OBJECT) {
126 DbgPrint("initialized\n");
128 type = G_TYPE_DBUS_ARG_INFO;
129 if (type != G_TYPE_OBJECT) {
130 DbgPrint("initialized\n");
132 type = G_TYPE_DBUS_AUTH_OBSERVER;
133 if (type != G_TYPE_OBJECT) {
134 DbgPrint("initialized\n");
136 type = G_TYPE_DBUS_CALL_FLAGS;
137 if (type != G_TYPE_OBJECT) {
138 DbgPrint("initialized\n");
140 type = G_TYPE_DBUS_CAPABILITY_FLAGS;
141 if (type != G_TYPE_OBJECT) {
142 DbgPrint("initialized\n");
144 type = G_TYPE_DBUS_CONNECTION;
145 if (type != G_TYPE_OBJECT) {
146 DbgPrint("initialized\n");
148 type = G_TYPE_DBUS_CONNECTION_FLAGS;
149 if (type != G_TYPE_OBJECT) {
150 DbgPrint("initialized\n");
152 type = G_TYPE_DBUS_ERROR;
153 if (type != G_TYPE_OBJECT) {
154 DbgPrint("initialized\n");
156 type = G_TYPE_DBUS_INTERFACE;
157 if (type != G_TYPE_OBJECT) {
158 DbgPrint("initialized\n");
160 type = G_TYPE_DBUS_INTERFACE_INFO;
161 if (type != G_TYPE_OBJECT) {
162 DbgPrint("initialized\n");
164 type = G_TYPE_DBUS_INTERFACE_SKELETON;
165 if (type != G_TYPE_OBJECT) {
166 DbgPrint("initialized\n");
168 type = G_TYPE_DBUS_INTERFACE_SKELETON_FLAGS;
169 if (type != G_TYPE_OBJECT) {
170 DbgPrint("initialized\n");
172 type = G_TYPE_DBUS_MENU_MODEL;
173 if (type != G_TYPE_OBJECT) {
174 DbgPrint("initialized\n");
176 type = G_TYPE_DBUS_MESSAGE;
177 if (type != G_TYPE_OBJECT) {
178 DbgPrint("initialized\n");
180 type = G_TYPE_DBUS_MESSAGE_BYTE_ORDER;
181 if (type != G_TYPE_OBJECT) {
182 DbgPrint("initialized\n");
184 type = G_TYPE_DBUS_MESSAGE_FLAGS;
185 if (type != G_TYPE_OBJECT) {
186 DbgPrint("initialized\n");
188 type = G_TYPE_DBUS_MESSAGE_HEADER_FIELD;
189 if (type != G_TYPE_OBJECT) {
190 DbgPrint("initialized\n");
192 type = G_TYPE_DBUS_MESSAGE_TYPE;
193 if (type != G_TYPE_OBJECT) {
194 DbgPrint("initialized\n");
196 type = G_TYPE_DBUS_METHOD_INFO;
197 if (type != G_TYPE_OBJECT) {
198 DbgPrint("initialized\n");
200 type = G_TYPE_DBUS_METHOD_INVOCATION;
201 if (type != G_TYPE_OBJECT) {
202 DbgPrint("initialized\n");
204 type = G_TYPE_DBUS_NODE_INFO;
205 if (type != G_TYPE_OBJECT) {
206 DbgPrint("initialized\n");
208 type = G_TYPE_DBUS_OBJECT;
209 if (type != G_TYPE_OBJECT) {
210 DbgPrint("initialized\n");
212 type = G_TYPE_DBUS_OBJECT_MANAGER;
213 if (type != G_TYPE_OBJECT) {
214 DbgPrint("initialized\n");
216 type = G_TYPE_DBUS_OBJECT_MANAGER_CLIENT;
217 if (type != G_TYPE_OBJECT) {
218 DbgPrint("initialized\n");
220 type = G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS;
221 if (type != G_TYPE_OBJECT) {
222 DbgPrint("initialized\n");
224 type = G_TYPE_DBUS_OBJECT_MANAGER_SERVER;
225 if (type != G_TYPE_OBJECT) {
226 DbgPrint("initialized\n");
228 type = G_TYPE_DBUS_OBJECT_PROXY;
229 if (type != G_TYPE_OBJECT) {
230 DbgPrint("initialized\n");
232 type = G_TYPE_DBUS_OBJECT_SKELETON;
233 if (type != G_TYPE_OBJECT) {
234 DbgPrint("initialized\n");
236 type = G_TYPE_DBUS_PROPERTY_INFO;
237 if (type != G_TYPE_OBJECT) {
238 DbgPrint("initialized\n");
240 type = G_TYPE_DBUS_PROPERTY_INFO_FLAGS;
241 if (type != G_TYPE_OBJECT) {
242 DbgPrint("initialized\n");
244 type = G_TYPE_DBUS_PROXY;
245 if (type != G_TYPE_OBJECT) {
246 DbgPrint("initialized\n");
248 type = G_TYPE_DBUS_PROXY_FLAGS;
249 if (type != G_TYPE_OBJECT) {
250 DbgPrint("initialized\n");
252 type = G_TYPE_DBUS_SEND_MESSAGE_FLAGS;
253 if (type != G_TYPE_OBJECT) {
254 DbgPrint("initialized\n");
256 type = G_TYPE_DBUS_SERVER;
257 if (type != G_TYPE_OBJECT) {
258 DbgPrint("initialized\n");
260 type = G_TYPE_DBUS_SERVER_FLAGS;
261 if (type != G_TYPE_OBJECT) {
262 DbgPrint("initialized\n");
264 type = G_TYPE_DBUS_SIGNAL_FLAGS;
265 if (type != G_TYPE_OBJECT) {
266 DbgPrint("initialized\n");
268 type = G_TYPE_DBUS_SIGNAL_INFO;
269 if (type != G_TYPE_OBJECT) {
270 DbgPrint("initialized\n");
272 type = G_TYPE_DBUS_SUBTREE_FLAGS;
273 if (type != G_TYPE_OBJECT) {
274 DbgPrint("initialized\n");
276 type = JSON_TYPE_NODE;
277 if (type != G_TYPE_OBJECT) {
278 DbgPrint("initialized\n");
280 type = JSON_TYPE_OBJECT;
281 if (type != G_TYPE_OBJECT) {
282 DbgPrint("initialized\n");
284 type = JSON_TYPE_ARRAY;
285 if (type != G_TYPE_OBJECT) {
286 DbgPrint("initialized\n");
288 type = JSON_TYPE_ARRAY;
289 if (type != G_TYPE_OBJECT) {
290 DbgPrint("initialized\n");
292 type = JSON_TYPE_SERIALIZABLE;
293 if (type != G_TYPE_OBJECT) {
294 DbgPrint("initialized\n");
296 type = JSON_TYPE_PARSER;
297 if (type != G_TYPE_OBJECT) {
298 DbgPrint("initialized\n");
300 type = JSON_TYPE_GENERATOR;
301 if (type != G_TYPE_OBJECT) {
302 DbgPrint("initialized\n");
306 static bool app_create(void *argv)
310 elm_app_base_scale_set(WVGA_DEFAULT_SCALE);
313 if (!widget_conf_is_loaded()) {
314 ret = widget_conf_load();
316 DbgPrint("Configureation manager is initiated: %d\n", ret);
320 critical_log_init(util_basename(((char **)argv)[0]));
323 * Touch the glib type system
325 initialize_glib_type_system();
327 DbgPrint("Scale factor: %lf\n", elm_config_scale_get());
329 if (WIDGET_CONF_COM_CORE_THREAD) {
330 if (setenv("PROVIDER_COM_CORE_THREAD", "true", 0) < 0) {
331 ErrPrint("setenv: %d\n", errno);
334 if (setenv("PROVIDER_COM_CORE_THREAD", "false", 0) < 0){
335 ErrPrint("setenv: %d\n", errno);
339 ret = widget_service_init();
341 DbgPrint("Livebox service init: %d\n", ret);
346 * Slave is not able to initiate system, before
347 * receive its name from the master
349 * So create callback doesn't do anything.
351 ret = fault_init(argv);
353 DbgPrint("Crash recover is initiated: %d\n", ret);
356 ret = update_monitor_init();
358 DbgPrint("Content update monitor is initiated: %d\n", ret);
361 ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, time_changed_cb, NULL);
363 DbgPrint("System time changed event callback added: %d\n", ret);
366 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, mmc_changed_cb, NULL);
368 DbgPrint("MMC status changed event callback added: %d\n", ret);
371 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, tts_changed_cb, NULL);
373 DbgPrint("TTS changed callback is added: %s\n", ret);
376 #if defined(ENABLE_EFL_ASSIST)
377 s_info.table = ea_theme_font_table_new("/usr/share/themes/FontInfoTable.xml");
379 DbgPrint("FONT TABLE Prepared");
380 ea_theme_fonts_set(s_info.table);
382 ea_theme_event_callback_add(EA_THEME_CALLBACK_TYPE_FONT, font_changed_cb, NULL);
384 font_changed_cb(NULL);
385 theme_loader_load(THEME_DIR);
389 widget_viewer_init();
394 static void app_terminate(void *data)
398 DbgPrint("Terminating provider\n");
400 widget_viewer_fini();
402 #if defined(ENABLE_EFL_ASSIST)
403 theme_loader_unload();
406 DbgPrint("FONT TABLE Destroyed");
407 ea_theme_font_table_free(s_info.table);
411 ea_theme_event_callback_del(EA_THEME_CALLBACK_TYPE_FONT, font_changed_cb);
414 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, tts_changed_cb);
416 DbgPrint("TTS changed callback is added: %s\n", ret);
419 ret = vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, time_changed_cb);
421 DbgPrint("Remove time changed callback: %d\n", ret);
424 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS, mmc_changed_cb);
426 DbgPrint("Remove MMC status changed callback: %d\n", ret);
429 ret = update_monitor_fini();
431 DbgPrint("Content update monitor is finalized: %d\n", ret);
436 DbgPrint("Crash recover is finalized: %d\n", ret);
441 DbgPrint("client finalized: %d\n", ret);
444 ret = widget_service_fini();
446 DbgPrint("widget service fini: %d\n", ret);
455 static void app_pause(void *data)
457 /* Will not be invoked */
461 static void app_resume(void *data)
463 /* Will not be invoked */
467 static void app_region_changed(app_event_info_h event_info, void *data)
470 // app_event_get_region_format(event_info, ®ion);
471 widget_system_event_all(WIDGET_SYS_EVENT_REGION_CHANGED);
474 static void app_language_changed(app_event_info_h event_info, void *data)
477 // app_event_get_language(event_info, &lang);
478 widget_system_event_all(WIDGET_SYS_EVENT_LANG_CHANGED);
481 static void app_control(app_control_h service, void *data)
486 char *hw_acceleration = NULL;
488 static int initialized = 0;
491 ErrPrint("Already initialized\n");
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");
501 ret = app_control_get_extra_data(service, WIDGET_CONF_BUNDLE_SLAVE_SECURED, &secured);
502 if (ret != APP_CONTROL_ERROR_NONE) {
504 ErrPrint("Secured is not valid\n");
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");
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);
522 if (!strcasecmp(secured, "true")) {
523 /* Don't use the update timer */
524 widget_turn_secured_on();
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());
533 if (hw_acceleration && !strcasecmp(hw_acceleration, "use-gl")) {
534 DbgPrint("Turn on: opengl_x11\n");
535 elm_config_accel_preference_set("opengl");
540 free(hw_acceleration);
547 #if defined(_ENABLE_MCHECK)
548 static inline void mcheck_cb(enum mcheck_status status)
552 ptr = util_get_current_module(NULL);
555 case MCHECK_DISABLED:
556 ErrPrint("[DISABLED] Heap incosistency detected: %s\n", ptr);
559 ErrPrint("[OK] Heap incosistency detected: %s\n", ptr);
562 ErrPrint("[HEAD] Heap incosistency detected: %s\n", ptr);
565 ErrPrint("[TAIL] Heap incosistency detected: %s\n", ptr);
568 ErrPrint("[FREE] Heap incosistency detected: %s\n", ptr);
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[])
581 ui_app_lifecycle_callback_s event_callback;
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]);
589 #if defined(_ENABLE_MCHECK)
592 option = getenv("PROVIDER_DISABLE_CALL_OPTION");
593 if (option && !strcasecmp(option, "true")) {
594 fault_disable_call_option();
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");
608 if (setenv("BUFMGR_LOCK_TYPE", "once", 0) < 0) {
609 ErrPrint("setenv: %d\n", errno);
612 if (setenv("BUFMGR_MAP_CACHE", "true", 0) < 0) {
613 ErrPrint("setenv: %d\n", errno);
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;
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
628 ret = ui_app_main(argc, argv, &event_callback, (void *)argv);
629 ErrPrint("ui_app_main: %d\n", ret);
631 if (s_info.heap_monitor) {
632 if (dlclose(s_info.heap_monitor) < 0) {
633 ErrPrint("dlclose: %d\n", errno);
640 HAPI int main_heap_monitor_is_enabled(void)
642 return s_info.heap_monitor_initialized ? s_info.heap_monitor_initialized() : 0;
645 HAPI size_t main_heap_monitor_target_usage(const char *name)
647 return s_info.heap_monitor_target_usage ? s_info.heap_monitor_target_usage(name) : 0;
650 HAPI int main_heap_monitor_add_target(const char *name)
652 return s_info.heap_monitor_add_target ? s_info.heap_monitor_add_target(name) : 0;
655 HAPI int main_heap_monitor_del_target(const char *name)
657 return s_info.heap_monitor_del_target ? s_info.heap_monitor_del_target(name) : 0;
660 HAPI void main_app_exit(void)