modules/information/ext_storage: fix sigsegv
[apps/core/preloaded/indicator-win.git] / src / main.c
1 /*
2  *  Indicator
3  *
4  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <app.h>
22 #include <vconf.h>
23 #include <unistd.h>
24 #include <app_manager.h>
25 #include <signal.h>
26 #include <feedback.h>
27 #include <notification.h>
28 #include <app_preference.h>
29 #include <wifi.h>
30 //FIXME
31 #if 0
32 #include <tzsh_indicator_service.h>
33 #endif
34 #include <vconf/vconf-internal-idle-lock-keys.h>
35
36 #include "common.h"
37 #include "box.h"
38 #include "icon.h"
39 #include "main.h"
40 #include "indicator_gui.h"
41 #include "modules.h"
42 #include "util.h"
43 #include "message.h"
44 #include "tts.h"
45 #include "log.h"
46 #include "indicator.h"
47 #include "ticker.h"
48
49 #define GRP_NAME "indicator"
50 #define WIN_TITLE "Illume Indicator"
51 #define VCONF_PHONE_STATUS "memory/startapps/sequence"
52
53 #define BUS_NAME       "org.tizen.system.deviced"
54 #define PATH_NAME    "/Org/Tizen/System/DeviceD/Display"
55 #define INTERFACE_NAME BUS_NAME".display"
56 #define MEMBER_NAME     "LCDOn"
57
58 #define MP_APP_ID "org.tizen.music-player-lite"
59 #define FMRADIO_APP_ID "org.tizen.fm-radio-lite"
60 #define VR_APP_ID "org.tizen.voicerecorder-lite"
61
62 #define STR_ATOM_MV_INDICATOR_GEOMETRY          "_E_MOVE_INDICATOR_GEOMETRY"
63
64 #define HIBERNATION_ENTER_NOTI  "HIBERNATION_ENTER"
65 #define HIBERNATION_LEAVE_NOTI  "HIBERNATION_LEAVE"
66
67 #define UNLOCK_ENABLED  0
68 #define TIMEOUT                 5
69
70 #ifdef HOME_KEY_EMULATION
71 /* Predefine string */
72 #define PROP_HWKEY_EMULATION "_HWKEY_EMULATION"
73 #define KEY_MSG_PREFIX_PRESS "P:"
74 #define KEY_MSG_PREFIX_RELEASE "R:"
75 #define KEY_MSG_PREFIX_PRESS_C "PC"
76 #define KEY_MSG_PREFIX_RELEASE_C "RC"
77
78 #ifndef KEY_HOME
79 #define KEY_HOME "XF86Phone"
80 #endif /* KEY_HOME */
81 #endif /* HOME_KEY_EMULATION */
82
83 //static E_DBus_Connection *edbus_conn=NULL;
84 //static E_DBus_Signal_Handler *edbus_handler=NULL;
85 static Eina_Bool home_button_pressed = EINA_FALSE;
86 static Eina_Bool show_hide_pressed = EINA_FALSE;
87 Evas_Coord_Point indicator_press_coord = {0,0};
88 Ecore_Timer *clock_timer;
89 int is_transparent = 0;
90 int current_angle = 0;
91 int current_state = 0;
92 #if 0
93 static int bFirst_opacity = 1;
94 #endif
95
96 static struct _s_info {
97         Ecore_Timer *listen_timer;
98 } s_info = {
99         .listen_timer = NULL,
100 };
101
102
103 static indicator_error_e _start_indicator(void *data);
104 static indicator_error_e _terminate_indicator(void *data);
105
106 static void _indicator_low_bat_cb(app_event_info_h event_info, void *data);
107 static void _indicator_lang_changed_cb(app_event_info_h event_info, void *data);
108 static void _indicator_region_changed_cb(app_event_info_h event_info, void *data);
109 static void _indicator_window_delete_cb(void *data, Evas_Object * obj, void *event);
110 //static Eina_Bool _indicator_client_message_cb(void *data, int type, void *event);
111 static void _indicator_mouse_down_cb(void *data, Evas * e, Evas_Object * obj, void *event);
112 static void _indicator_mouse_move_cb(void *data, Evas * e, Evas_Object * obj, void *event);
113 static void _indicator_mouse_up_cb(void *data, Evas * e, Evas_Object * obj, void *event);
114
115
116 static void _indicator_low_bat_cb(app_event_info_h event_info, void *data)
117 {
118 }
119
120 static void _indicator_lang_changed_cb(app_event_info_h event_info, void *data)
121 {
122         modules_lang_changed(data);
123 }
124
125 static void _indicator_region_changed_cb(app_event_info_h event_info, void *data)
126 {
127         modules_region_changed(data);
128 }
129
130 static void _indicator_window_delete_cb(void *data, Evas_Object * obj, void *event)
131 {
132         ret_if(!data);
133
134         _terminate_indicator((struct appdata *)data);
135 }
136
137 static void _indicator_notify_pm_state_cb(keynode_t * node, void *data)
138 {
139         static int nMove = 0;
140         static int nIndex = 1;
141         int val = -1;
142
143         ret_if(!data);
144
145         if (vconf_get_int(VCONFKEY_PM_STATE, &val) < 0) return;
146
147         switch (val) {
148         case VCONFKEY_PM_STATE_LCDOFF:
149                 if (clock_timer != NULL) {
150                         ecore_timer_del(clock_timer);
151                         clock_timer = NULL;
152                 }
153         case VCONFKEY_PM_STATE_SLEEP: // lcd off 2
154                 /* FIXME */
155                 nMove = nMove+nIndex;
156                 if(nMove>=4)
157                         nIndex = -1;
158                 else if(nMove<=0)
159                         nIndex = 1;
160                 {
161                         char temp[30] = {0,};
162                         sprintf(temp,"indicator.padding.resize.%d",nMove);
163                         util_signal_emit(data,temp,"indicator.prog");
164                 }
165                 icon_set_update_flag(0);
166                 box_noti_ani_handle(0);
167                 break;
168         case VCONFKEY_PM_STATE_NORMAL:
169                 if (!icon_get_update_flag()) {
170                         icon_set_update_flag(1);
171                         box_noti_ani_handle(1);
172                         modules_wake_up(data);
173                 }
174                 break;
175         case VCONFKEY_PM_STATE_LCDDIM:
176         default:
177                 break;
178         }
179 }
180
181 static void _indicator_power_off_status_cb(keynode_t * node, void *data)
182 {
183         int val = -1;
184
185         ret_if(!data);
186
187         if (vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val) < 0) return;
188
189         switch (val) {
190         case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
191         case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
192                 ui_app_exit();
193                 break;
194         default:
195                 break;
196         }
197
198 }
199
200 static void _indicator_lock_status_cb(keynode_t * node, void *data)
201 {
202         static int lockstate = 0;
203         extern int clock_mode;
204         int val = -1;
205
206         ret_if(!data);
207
208         if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) return;
209         if (val == lockstate) return;
210
211         lockstate = val;
212
213         switch (val) {
214         case VCONFKEY_IDLE_UNLOCK:
215                 if (!clock_mode) util_signal_emit(data,"clock.font.12","indicator.prog");
216                 else util_signal_emit(data,"clock.font.24","indicator.prog");
217                 break;
218         case VCONFKEY_IDLE_LOCK:
219         case VCONFKEY_IDLE_LAUNCHING_LOCK:
220                 util_signal_emit(data,"clock.invisible","indicator.prog");
221                 break;
222         default:
223                 break;
224         }
225
226 }
227
228 #if 0
229 static void _rotate_window(struct appdata *ad, int new_angle)
230 {
231         ret_if(!ad);
232
233         _D("Indicator angle is %d degree", new_angle);
234
235         current_angle = new_angle;
236
237         switch (new_angle) {
238                 case 0:
239                 case 180:
240                         evas_object_resize(ad->win.win, ad->win.port_w, ad->win.h);
241                         break;
242                 case 90:
243                 case 270:
244                         evas_object_resize(ad->win.win, ad->win.land_w, ad->win.h);
245                         break;
246                 default:
247                         break;
248         }
249 }
250 #endif
251
252 #if 0
253 static void _change_opacity(void *data, enum indicator_opacity_mode mode)
254 {
255         struct appdata *ad = NULL;
256         const char *signal = NULL;
257         retif(data == NULL, , "Invalid parameter!");
258
259         ad = data;
260
261         if (bFirst_opacity==1) bFirst_opacity = 0;
262
263         switch (mode) {
264         case INDICATOR_OPACITY_OPAQUE:
265                 signal = "bg.opaque";
266                 ad->opacity_mode = mode;
267                 break;
268         case INDICATOR_OPACITY_TRANSLUCENT:
269                 signal = "bg.translucent";
270                 ad->opacity_mode = mode;
271                 break;
272         case INDICATOR_OPACITY_TRANSPARENT:
273                 signal = "bg.transparent";
274                 ad->opacity_mode = mode;
275                 break;
276         default:
277                 _E("unknown mode : %d", mode);
278                 signal = "bg.opaque";
279                 ad->opacity_mode = INDICATOR_OPACITY_OPAQUE;
280                 break;
281
282         }
283         util_signal_emit_by_win(&(ad->win),signal, "indicator.prog");
284 }
285 #endif
286
287 #if 0
288 static void _indicator_quickpanel_changed(void *data, int is_open)
289 {
290         int val = 0;
291
292         ret_if(!data);
293
294         if (vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &val) < 0) return;
295         if (val == VCONFKEY_IDLE_LOCK) return;
296 }
297 #endif
298
299 #if 0
300 static Eina_Bool _indicator_client_message_cb(void *data, int type, void *event)
301 {
302         Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *) event;
303         struct appdata *ad = NULL;
304         ad = data;
305
306         retv_if(data == NULL || event == NULL, ECORE_CALLBACK_RENEW);
307         if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) {
308                 if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON) {
309                         _indicator_quickpanel_changed(data, 1);
310                 } else if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF) {
311                         _indicator_quickpanel_changed(data, 0);
312                 }
313         }
314
315         if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE) {
316                 int new_angle = 0;
317                 if(ev->win != ad->active_indi_win) {
318                         return ECORE_CALLBACK_RENEW;
319                 }
320                 new_angle = ev->data.l[0];
321                 _rotate_window(ad, new_angle);
322         }
323         return EINA_TRUE;
324 }
325 #endif
326
327 /* this function will be reused */
328 #if 0
329 static Eina_Bool _active_indicator_handle(void* data,int type)
330 {
331         int trans_mode = 0;
332         int angle = 0;
333 //      Ecore_X_Illume_Indicator_Opacity_Mode illume_opacity = 0;
334
335         retv_if(!data, EINA_FALSE);
336
337         struct appdata *ad = (struct appdata *)data;
338         switch (type) {
339         /* Opacity */
340         case 1:
341                 illume_opacity = ecore_x_e_illume_indicator_opacity_get(ad->active_indi_win);
342
343                 switch(illume_opacity) {
344                 case ECORE_X_ILLUME_INDICATOR_OPAQUE:
345                         trans_mode = INDICATOR_OPACITY_OPAQUE;
346                         break;
347                 case ECORE_X_ILLUME_INDICATOR_TRANSLUCENT:
348                         trans_mode = INDICATOR_OPACITY_TRANSLUCENT;
349                         break;
350                 case ECORE_X_ILLUME_INDICATOR_TRANSPARENT:
351                         trans_mode = INDICATOR_OPACITY_TRANSPARENT;
352                         break;
353                 default:
354                         trans_mode = INDICATOR_OPACITY_OPAQUE;
355                         break;
356                 }
357
358                 _change_opacity(ad, trans_mode);
359                 break;
360         /* Rotate */
361         case 2:
362                 util_win_prop_angle_get(ad->active_indi_win, &angle);
363                 _rotate_window(ad, angle);
364                 break;
365         default :
366                 break;
367         }
368
369         return EINA_TRUE;
370 }
371 #endif
372
373 /* this function will be reused */
374 #if 0
375 static Eina_Bool _property_changed_cb(void *data, int type, void *event)
376 {
377         struct appdata *ad = data;
378         Ecore_X_Event_Window_Property *ev = event;
379
380         retv_if(!ad, ECORE_CALLBACK_PASS_ON);
381         retv_if(!ev, ECORE_CALLBACK_PASS_ON);
382
383         if (ev->atom == ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE) {
384                 if (ev->win == ad->active_indi_win) {
385                         _active_indicator_handle(data, 2);
386                 }
387         } else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_OPACITY_MODE) {
388                 if (ev->win == ad->active_indi_win) {
389                         _active_indicator_handle(data, 1);
390                 }
391         } else if (ev->atom == ad->atom_active) {
392                 int ret = 0;
393
394                 Ecore_X_Window active_win;
395
396                 ret = ecore_x_window_prop_window_get(ecore_x_window_root_first_get(), ad->atom_active, &(active_win), 1);
397                 if (ret <= -1) {
398                         _E("Count of fetched items : %d", ret);
399                         return ECORE_CALLBACK_PASS_ON;
400                 }
401
402                 if (active_win != ad->active_indi_win) {
403                         if (ad->active_indi_win != -1) {
404                                 ecore_x_window_unsniff(ad->active_indi_win);
405                                 _D("UNSNIFF API %x", ad->active_indi_win);
406                         }
407                         ad->active_indi_win = active_win;
408
409                         ecore_x_window_sniff(ad->active_indi_win);
410                 }
411
412                 _active_indicator_handle(data, 1);
413                 _active_indicator_handle(data, 2);
414         }
415
416         return ECORE_CALLBACK_PASS_ON;
417 }
418 #endif
419
420 #if 0
421 static void _mctrl_monitor_cb(minicontrol_action_e action, const char *name, unsigned int width, unsigned int height, minicontrol_priority_e priority, void *data)
422 {
423         ret_if(!data);
424         ret_if(!name);
425
426         modules_minictrl_control(action,name,data);
427 }
428 #endif
429
430 static void _indicator_ecore_evas_msg_parent_handle(Ecore_Evas *ee, int msg_domain, int msg_id, void *data, int size)
431 {
432         ret_if(!data);
433
434 #ifdef _SUPPORT_SCREEN_READER
435         if (msg_domain == MSG_DOMAIN_CONTROL_ACCESS) {
436                 struct appdata *ad = (struct appdata *)ecore_evas_data_get(ee,"indicator_app_data");
437
438                 ret_if(!ad);
439
440                 Elm_Access_Action_Info *action_info;
441                 Evas_Object* win = NULL;
442                 action_info = data;
443
444                 win = ad->win.win;
445
446                 if (msg_id == ELM_ACCESS_ACTION_ACTIVATE) {
447                         elm_access_action(win, action_info->action_type,action_info);
448                 } else if (msg_id == ELM_ACCESS_ACTION_HIGHLIGHT_NEXT) {
449                         action_info->highlight_cycle = EINA_TRUE;
450                         elm_access_action(win,action_info->action_type,action_info);
451                 } else if (msg_id == ELM_ACCESS_ACTION_HIGHLIGHT_PREV) {
452                         action_info->highlight_cycle = EINA_TRUE;
453                         elm_access_action(win,action_info->action_type,action_info);
454                 } else if (msg_id == ELM_ACCESS_ACTION_UNHIGHLIGHT) {
455                         elm_access_action(win,action_info->action_type,action_info);
456                 } else if (msg_id == ELM_ACCESS_ACTION_READ) {
457                         elm_access_action(win,action_info->action_type,action_info);
458                 }
459         }
460 #endif /* _SUPPORT_SCREEN_READER */
461 }
462
463 #if 0
464 static void on_changed_receive(void *data, DBusMessage *msg)
465 {
466         int r;
467
468         r = dbus_message_is_signal(msg, INTERFACE_NAME, MEMBER_NAME);
469         ret_if(!r);
470
471         _D("LCD On handling");
472
473         if (!icon_get_update_flag()) {
474                 icon_set_update_flag(1);
475                 box_noti_ani_handle(1);
476                 modules_wake_up(data);
477         }
478 }
479
480 static void edbus_cleaner(void)
481 {
482         if (!edbus_conn) {
483                 _D("already unregistered");
484                 return;
485         }
486
487         if (edbus_handler) {
488                 e_dbus_signal_handler_del(edbus_conn, edbus_handler);
489                 edbus_handler = NULL;
490         }
491
492         if (edbus_conn) {
493                 e_dbus_connection_close(edbus_conn);
494                 edbus_conn = NULL;
495         }
496
497         e_dbus_shutdown();
498 }
499
500 static int edbus_listener(void* data)
501 {
502         if (edbus_conn != NULL) {
503                 _D("alreay exist");
504                 return -1;
505         }
506
507         e_dbus_init();
508
509         edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
510         if (!edbus_conn) {
511                 _E("e_dbus_bus_get error");
512                 return -1;
513         }
514
515         edbus_handler = e_dbus_signal_handler_add(edbus_conn, NULL, PATH_NAME, INTERFACE_NAME, MEMBER_NAME, on_changed_receive, data);
516         if (!edbus_handler) {
517                 _E("e_dbus_signal_handler_add error");
518                 return -1;
519         }
520
521         return 0;
522 }
523 #endif
524
525 static void _register_event_handler_both(win_info *win, void *data)
526 {
527         Ecore_Evas *ee;
528
529         ret_if(!win);
530
531         ee = ecore_evas_ecore_evas_get(evas_object_evas_get(win->win));
532
533         evas_object_smart_callback_add(win->win,"delete,request", _indicator_window_delete_cb, data);
534         evas_object_event_callback_add(win->layout, EVAS_CALLBACK_MOUSE_DOWN, _indicator_mouse_down_cb, win);
535         evas_object_event_callback_add(win->layout, EVAS_CALLBACK_MOUSE_MOVE, _indicator_mouse_move_cb, win);
536         evas_object_event_callback_add(win->layout, EVAS_CALLBACK_MOUSE_UP,_indicator_mouse_up_cb, win);
537         ecore_evas_callback_msg_parent_handle_set(ee, _indicator_ecore_evas_msg_parent_handle);
538         ecore_evas_data_set(ee,"indicator_app_data",data);
539 }
540
541 /* FIXME */
542 #if 0
543 static void _indicator_service_cb(void *data, tzsh_indicator_service_h service, int angle, int opacity)
544 {
545         _D("Indicator service callback");
546 }
547 #endif
548
549 static void register_event_handler(void *data)
550 {
551         struct appdata *ad = data;
552 //      Ecore_Event_Handler *hdl = NULL;
553         ret_if(!data);
554
555         ad->active_indi_win = -1;
556         //ad->atom_active = ecore_x_atom_get("_NET_ACTIVE_WINDOW");
557         //ecore_x_window_sniff(ecore_x_window_root_first_get());
558
559         _register_event_handler_both(&(ad->win),data);
560
561         /* FIXME */
562 #if 0
563         if (ad->indicator_service) {
564                 tzsh_indicator_service_property_change_cb_set(ad->indicator_service, _indicator_service_cb, NULL);
565         }
566 #endif
567
568 #if 0
569         hdl = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _indicator_client_message_cb, (void *)ad);
570         ret_if(!hdl);
571         ad->evt_handlers = eina_list_append(ad->evt_handlers, hdl);
572
573         hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _property_changed_cb, data);
574         ret_if(!hdl);
575         ad->evt_handlers = eina_list_append(ad->evt_handlers, hdl);
576 #endif
577         if (vconf_notify_key_changed(VCONFKEY_PM_STATE, _indicator_notify_pm_state_cb, (void *)ad) != 0) {
578                 _E("Fail to set callback for VCONFKEY_PM_STATE");
579         }
580
581         if (vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, _indicator_power_off_status_cb, (void *)ad) < 0) {
582                 _E("Failed to set callback for VCONFKEY_SYSMAN_POWER_OFF_STATUS");
583         }
584
585         if (vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE, _indicator_lock_status_cb, (void *)ad) < 0) {
586                 _E("Failed to set callback for VCONFKEY_IDLE_LOCK_STATE");
587         }
588
589 //      edbus_listener(data);
590 }
591
592 static void _unregister_event_handler_both(win_info *win)
593 {
594         ret_if(!win);
595
596         evas_object_smart_callback_del(win->win, "delete-request", _indicator_window_delete_cb);
597         evas_object_event_callback_del(win->layout, EVAS_CALLBACK_MOUSE_DOWN, _indicator_mouse_down_cb);
598         evas_object_event_callback_del(win->layout, EVAS_CALLBACK_MOUSE_MOVE, _indicator_mouse_move_cb);
599         evas_object_event_callback_del(win->layout, EVAS_CALLBACK_MOUSE_UP, _indicator_mouse_up_cb);
600 }
601
602 static int unregister_event_handler(void *data)
603 {
604         struct appdata *ad = (struct appdata *)data;
605
606         retv_if(!data, 0);
607
608         _unregister_event_handler_both(&(ad->win));
609
610         vconf_ignore_key_changed(VCONFKEY_PM_STATE, _indicator_notify_pm_state_cb);
611         vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, _indicator_power_off_status_cb);
612         vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE, _indicator_lock_status_cb);
613
614         Ecore_Event_Handler *hdl = NULL;
615         EINA_LIST_FREE(ad->evt_handlers, hdl) {
616                 if (hdl) ecore_event_handler_del(hdl);
617         }
618
619 //      edbus_cleaner();
620
621         return OK;
622 }
623
624 static void _create_layout(struct appdata *ad, const char *file, const char *group)
625 {
626         ad->win.layout = elm_layout_add(ad->win.win);
627         ret_if(!ad->win.layout);
628
629         if (EINA_FALSE == elm_layout_file_set(ad->win.layout, file, group)) {
630                 _E("Failed to set file of layout");
631                 evas_object_del(ad->win.layout);
632                 return;
633         }
634
635         evas_object_size_hint_min_set(ad->win.layout, ad->win.w, ad->win.h);
636         /* FIXME */
637         evas_object_size_hint_weight_set(ad->win.layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
638         elm_win_resize_object_add(ad->win.win, ad->win.layout);
639         evas_object_move(ad->win.layout, 0, 0);
640         evas_object_show(ad->win.layout);
641 }
642
643 static void _create_box(win_info *win)
644 {
645         ret_if(!win);
646
647         /* First, clear layout */
648         box_fini(win);
649
650         box_init(win);
651
652         return;
653 }
654
655 //FIXME
656 #if 0
657 static indicator_error_e _tzsh_set(struct appdata* ad)
658 {
659         tzsh_window tz_win;
660
661         retv_if(!ad, INDICATOR_ERROR_INVALID_PARAMETER);
662         retv_if(!ad->win.win, INDICATOR_ERROR_INVALID_PARAMETER);
663
664         ad->tzsh = tzsh_create(TZSH_TOOLKIT_TYPE_EFL);
665         retv_if(!ad->tzsh, INDICATOR_ERROR_FAIL);
666
667         tz_win = elm_win_window_id_get(ad->win.win);
668         if (!tz_win) {
669                 tzsh_destroy(ad->tzsh);
670                 _E("Failed to get Tizen window");
671                 /* FIXME */
672                 //return INDICATOR_ERROR_FAIL;
673                 return INDICATOR_ERROR_NONE;
674         }
675
676         ad->indicator_service = tzsh_indicator_service_create(ad->tzsh, tz_win);
677         if (!ad->indicator_service) {
678                 tzsh_destroy(ad->tzsh);
679                 _E("Failed to create Tizen window indicator service");
680                 return INDICATOR_ERROR_FAIL;
681         }
682
683         return INDICATOR_ERROR_NONE;
684 }
685
686 static void _tzsh_unset(struct appdata *ad)
687 {
688         ret_if(!ad);
689
690         if (ad->indicator_service) {
691                 tzsh_indicator_service_destroy(ad->indicator_service);
692                 ad->indicator_service = NULL;
693         }
694
695         if (ad->tzsh) {
696                 tzsh_destroy(ad->tzsh);
697                 ad->tzsh = NULL;
698         }
699 }
700 #endif
701
702 static Eina_Bool _indicator_listen_timer_cb(void* data)
703 {
704         win_info *win = data;
705
706         retv_if(!win, ECORE_CALLBACK_CANCEL);
707
708         //win = (win_info*)data;
709
710         if (!elm_win_socket_listen(win->win , INDICATOR_SERVICE_NAME, 0, EINA_FALSE)) {
711                 _E("failed to elm_win_socket_listen() %x", win->win);
712                 return ECORE_CALLBACK_RENEW;
713         } else {
714                 _D("listen success");
715                 s_info.listen_timer = NULL;
716                 return ECORE_CALLBACK_CANCEL;
717         }
718 }
719
720 #define INDICATOR_HEIGHT_TM1 52
721 static void _create_window(struct appdata *ad)
722 {
723         Evas_Object *dummy_win = NULL;
724
725         _D("Create window");
726
727         ad->win.win = elm_win_add(NULL, "indicator", ELM_WIN_SOCKET_IMAGE);
728         ret_if(!(ad->win.win));
729
730         elm_win_alpha_set(ad->win.win, EINA_TRUE);
731
732         dummy_win = elm_win_add(NULL, "indicator_dummy", ELM_WIN_BASIC);
733         if (dummy_win) {
734                 elm_win_screen_size_get(dummy_win, NULL, NULL, &ad->win.port_w, &ad->win.land_w);
735                 evas_object_del(dummy_win);
736                 _D("Dummy window w, h (%d, %d)", ad->win.port_w, ad->win.land_w);
737         } else {
738                 _E("Critical error. Cannot create dummy window");
739         }
740
741         if (!elm_win_socket_listen(ad->win.win , INDICATOR_SERVICE_NAME, 0, EINA_FALSE)) {
742                 _E("Failed 1st to elm_win_socket_listen() %x", ad->win.win);
743
744                 if (s_info.listen_timer != NULL) {
745                         ecore_timer_del(s_info.listen_timer);
746                         s_info.listen_timer = NULL;
747                 }
748                 s_info.listen_timer = ecore_timer_add(3, _indicator_listen_timer_cb, &(ad->win));
749         }
750
751         elm_win_alpha_set(ad->win.win , EINA_TRUE);
752         /* FIXME */
753         elm_win_borderless_set(ad->win.win , EINA_TRUE);
754         evas_object_size_hint_fill_set(ad->win.win , EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
755         evas_object_size_hint_align_set(ad->win.win , 1.0, 0.5);
756
757         evas_object_resize(ad->win.win, ad->win.port_w, INDICATOR_HEIGHT_TM1);
758         _D("w,h(%d,%d)", ad->win.port_w, INDICATOR_HEIGHT_TM1);
759
760         evas_object_show(ad->win.win);
761
762 }
763
764 static void _create_base_gui(void* data)
765 {
766         struct appdata *ad = data;
767
768         ret_if(!ad);
769
770         _D("Start to create base gui");
771
772         _create_window(ad);
773
774         //FIXME
775 #if 0
776         if (INDICATOR_ERROR_NONE != _tzsh_set(ad)) {
777                 _E("Failed to set tzsh");
778         }
779 #endif
780
781         /* FIXME */
782         ad->win.h = INDICATOR_HEIGHT_TM1;
783         ad->win.w = ad->win.port_w;
784         ad->win.evas = evas_object_evas_get(ad->win.win);
785
786         _D("win_size = Original(%d, %d), Scaled(%lf, %lf)", ad->win.port_w, ad->win.h, ELM_SCALE_SIZE(ad->win.port_w), ELM_SCALE_SIZE(ad->win.h));
787
788         _create_layout(ad, util_get_res_file_path(EDJ_FILE), GRP_NAME);
789         _create_box(&(ad->win));
790
791
792 #if 0 /* For test */
793         Evas_Object *rect = evas_object_rectangle_add(ad->win.evas);
794         ret_if(!rect);
795         evas_object_resize(rect, 720, 52);
796         evas_object_color_set(rect, 0, 0, 255, 255);
797         evas_object_show(rect);
798         evas_object_layer_set(rect, -256);
799 #endif
800         ad->win.data = data;
801
802         return;
803 }
804
805 static void _init_win_info(void * data)
806 {
807         struct appdata *ad = data;
808
809         ret_if(!ad);
810
811         memset(&(ad->win),0x00,sizeof(win_info));
812 }
813
814 static void _init_tel_info(void * data)
815 {
816         struct appdata *ad = data;
817
818         ret_if(!ad);
819
820         memset(&(ad->tel_info), 0x00, sizeof(telephony_info));
821 }
822
823 static indicator_error_e _start_indicator(void *data)
824 {
825         retv_if(!data, INDICATOR_ERROR_INVALID_PARAMETER);
826
827         _init_win_info(data);
828         _init_tel_info(data);
829
830         /* Create indicator window */
831         _create_base_gui(data);
832
833         return INDICATOR_ERROR_NONE;
834 }
835
836 static indicator_error_e _terminate_indicator(void *data)
837 {
838         struct appdata *ad = data;
839
840         retv_if(!ad, INDICATOR_ERROR_INVALID_PARAMETER);
841
842         modules_fini(data);
843         unregister_event_handler(ad);
844
845         box_fini(&(ad->win));
846
847         if (ad->win.evas)
848                 evas_image_cache_flush(ad->win.evas);
849
850         if (ad->win.layout) {
851                 evas_object_del(ad->win.layout);
852                 ad->win.layout = NULL;
853         }
854
855         if (ad->win.win) {
856                 evas_object_del(ad->win.win);
857                 ad->win.win = NULL;
858         }
859
860         //FIXME
861 #if 0
862         _tzsh_unset(ad);
863 #endif
864
865         if (ad)
866                 free(ad);
867
868         elm_exit();
869
870         return INDICATOR_ERROR_NONE;
871 }
872
873 static void __indicator_set_showhide_press(int value, int line)
874 {
875         show_hide_pressed = value;
876 }
877
878 static void _indicator_mouse_down_cb(void *data, Evas * e, Evas_Object * obj, void *event)
879 {
880         win_info *win = (win_info*)data;
881         Evas_Event_Mouse_Down *ev = NULL;
882
883         retif(data == NULL || event == NULL, , "Invalid parameter!");
884         ev = event;
885
886         win->mouse_event.x = ev->canvas.x;
887         win->mouse_event.y = ev->canvas.y;
888
889         if (ev->button != 1) {
890                 return;
891         }
892
893 #ifdef HOME_KEY_EMULATION
894         if (box_check_indicator_area(win, ev->canvas.x, ev->canvas.y)) {
895                 int lock_state = VCONFKEY_IDLE_UNLOCK;
896                 int ps_state = -1;
897                 int ret = -1;
898
899         /*      if (indicator_message_disp_check(win->type) == 1) {
900                         return;
901                 }*/
902                 ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE,&lock_state);
903
904                 if (ret != 0 || lock_state == VCONFKEY_IDLE_LOCK) {
905                         return;
906                 }
907                 ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE,&ps_state);
908
909                 if (ret != 0 || ps_state == SETTING_PSMODE_EMERGENCY) {
910                         return;
911                 }
912
913                 if (box_check_home_icon_area(win, ev->canvas.x, ev->canvas.y)) {
914
915                         if (util_check_system_status() == FAIL) {
916                                 _D("util_check_system_status failed");
917                                 return;
918                         }
919                         home_button_pressed = EINA_TRUE;
920                 }
921                 indicator_press_coord.x = ev->canvas.x;
922                 indicator_press_coord.y = ev->canvas.y;
923         }
924 #endif
925 }
926
927
928
929 static void _indicator_mouse_move_cb(void *data, Evas * e, Evas_Object * obj, void *event)
930 {
931         Evas_Event_Mouse_Move *ev = NULL;
932         win_info* win = (win_info*)data;
933
934         retif(data == NULL || event == NULL, , "Invalid parameter!");
935
936         ev = event;
937
938         if (home_button_pressed) {
939                 if (!box_check_home_icon_area(win,ev->cur.canvas.x,ev->cur.canvas.y)) {
940                         home_button_pressed = false;
941                 }
942
943         }
944         if (show_hide_pressed == 1) {
945                         if (!box_check_more_icon_area(win,ev->cur.canvas.x,ev->cur.canvas.y)) {
946                                 __indicator_set_showhide_press(EINA_FALSE, __LINE__);
947                         }
948         }
949 }
950
951 static void _indicator_mouse_up_cb(void *data, Evas * e, Evas_Object * obj, void *event)
952 {
953         Evas_Event_Mouse_Up *ev = NULL;
954         win_info *win = (win_info *)data;
955
956         retif(data == NULL || event == NULL, , "Invalid parameter!");
957
958         ev = event;
959
960 #ifdef HOME_KEY_EMULATION
961         if (box_check_indicator_area(win, ev->canvas.x, ev->canvas.y)) {
962
963                 if (box_check_home_icon_area(win, ev->canvas.x, ev->canvas.y)) {
964                         if (home_button_pressed == EINA_TRUE) {
965                                 util_launch_search(win->data);
966                                 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_TAP);
967                         }
968
969                 } else if (box_check_more_icon_area(win, ev->canvas.x, ev->canvas.y)) {
970                         if(show_hide_pressed == EINA_TRUE) {
971                                 DBG("pressed area");
972                                 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_TAP);
973                         }
974                 }
975         }
976
977         home_button_pressed = EINA_FALSE;
978         __indicator_set_showhide_press(EINA_FALSE, __LINE__);
979
980 #else /* HOME_REMOVE_LONGPRESS */
981         int mouse_up_prio = -1;
982         int mouse_down_prio = -1;
983         int lock_state;
984
985         if (home_button_pressed == EINA_TRUE) {
986                 home_button_pressed = EINA_FALSE;
987         }
988
989         mouse_down_prio =
990                 box_get_priority_in_move_area(win,win->mouse_event.x,
991                                                         win->mouse_event.y);
992         mouse_up_prio = box_get_priority_in_move_area(win,ev->canvas.x,
993                                                         ev->canvas.y);
994
995         if (mouse_down_prio > -1 && mouse_up_prio > -1
996                 && mouse_down_prio == mouse_up_prio) {
997                 switch (mouse_down_prio) {
998                 case INDICATOR_PRIORITY_FIXED1:
999                         lock_state = VCONFKEY_IDLE_UNLOCK;
1000                         int lock_ret = -1;
1001
1002                         lock_ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE,
1003                                         &lock_state);
1004
1005                         /* In Lock Screen, home button don't have to do */
1006                         if (lock_ret == 0 && lock_state == VCONFKEY_IDLE_LOCK)
1007                                 break;
1008
1009                         if (util_check_system_status() == FAIL)
1010                                 break;
1011                 break;
1012                 }
1013         }
1014 #endif /* HOME_KEY_EMULATION */
1015         win->mouse_event.x = 0;
1016         win->mouse_event.y = 0;
1017 }
1018
1019 #if 0
1020 static void _app_terminate_cb(app_context_h app_context, app_context_status_e status, void *data)
1021 {
1022         retif(data == NULL, , "Invalid parameter!");
1023         DBG("_app_terminate_cb");
1024         char *app_id = NULL;
1025         app_context_get_app_id(app_context, &app_id);
1026         if (app_id == NULL) {
1027                 ERR("app_id is null!!");
1028                 return;
1029         } else {
1030                 DBG("_app_terminate_cb %s",app_id);
1031         }
1032
1033         if (status == APP_CONTEXT_STATUS_TERMINATED) {
1034                 if (strcmp(MP_APP_ID,app_id) == 0) {
1035                         DBG("hide music icon");
1036                         hide_mp_icon();
1037                 } else if(strcmp(FMRADIO_APP_ID,app_id) == 0) {
1038                         DBG("hide fm radio icon");
1039                         hide_fm_radio_icon();
1040                 } else if(strcmp(VR_APP_ID,app_id) == 0) {
1041                         DBG("hide voice recorder icon");
1042                         hide_voice_recorder_icon();
1043                 }
1044         }
1045         if (app_id!=NULL) {
1046                 free(app_id);
1047                 app_id = NULL;
1048         }
1049 }
1050
1051 static void register_app_terminate_cb(void* data)
1052 {
1053         retif(data == NULL, , "Invalid parameter!");
1054         app_manager_set_app_context_status_cb(_app_terminate_cb, MP_APP_ID, data);
1055         app_manager_set_app_context_status_cb(_app_terminate_cb, FMRADIO_APP_ID, data);
1056         app_manager_set_app_context_status_cb(_app_terminate_cb, VR_APP_ID, data);
1057 }
1058 #endif
1059
1060 static void _signal_handler(int signum, siginfo_t *info, void *unused)
1061 {
1062     ui_app_exit();
1063 }
1064
1065 static bool app_create(void *data)
1066 {
1067         struct appdata *ad = data;
1068         int ret;
1069
1070         retv_if(!ad, false);
1071
1072         elm_app_base_scale_set(2.6);
1073
1074         /* Signal handler */
1075         struct sigaction act;
1076         memset(&act, 0x00, sizeof(struct sigaction));
1077         act.sa_sigaction = _signal_handler;
1078         act.sa_flags = SA_SIGINFO;
1079
1080         ret = sigemptyset(&act.sa_mask);
1081         if (ret < 0) {
1082                 _E("Failed to sigemptyset[%s]", strerror(errno));
1083         }
1084         ret = sigaddset(&act.sa_mask, SIGTERM);
1085         if (ret < 0) {
1086                 _E("Failed to sigaddset[%s]", strerror(errno));
1087         }
1088         ret = sigaction(SIGTERM, &act, NULL);
1089         if (ret < 0) {
1090                 _E("Failed to sigaction[%s]", strerror(errno));
1091         }
1092
1093         ret = _start_indicator(ad);
1094         if (ret != INDICATOR_ERROR_NONE) {
1095                 _D("Failed to create a new window!");
1096         }
1097
1098         /* Set nonfixed-list size for display */
1099         modules_init_first(ad);
1100
1101         if (ad->win.win) {
1102                 elm_win_activate(ad->win.win);
1103         }
1104         evas_object_show(ad->win.layout);
1105         evas_object_show(ad->win.win);
1106
1107         return true;
1108 }
1109
1110 static void app_terminate(void *data)
1111 {
1112         struct appdata *ad = data;
1113         modules_fini(data);
1114         ticker_fini(ad);
1115         indicator_message_fini();
1116 #ifdef _SUPPORT_SCREEN_READER2
1117         indicator_service_tts_fini(data);
1118 #endif
1119
1120         unregister_event_handler(ad);
1121
1122         feedback_deinitialize();
1123
1124         box_fini(&(ad->win));
1125         evas_image_cache_flush(ad->win.evas);
1126         evas_object_del(ad->win.layout);
1127         evas_object_del(ad->win.win);
1128
1129         _D("INDICATOR IS TERMINATED");
1130 }
1131
1132 static void app_pause(void *data)
1133 {
1134 }
1135
1136 static void app_resume(void *data)
1137 {
1138 }
1139
1140 static void app_service(app_control_h service, void *data)
1141 {
1142         struct appdata *ad = data;
1143
1144         _D("INDICATOR IS STARTED");
1145
1146         register_event_handler(ad);
1147         modules_init(data);
1148 #ifdef _SUPPORT_SCREEN_READER
1149         modules_register_tts(data);
1150 #endif
1151         feedback_initialize();
1152         indicator_message_init(data);
1153         if (INDICATOR_ERROR_NONE != ticker_init(ad)) {
1154                 _E("Ticker cannot initialize");
1155         }
1156 #ifdef _SUPPORT_SCREEN_READER2
1157         indicator_service_tts_init(data);
1158 #endif
1159         _indicator_lock_status_cb(NULL, data);
1160 #if 0
1161         register_app_terminate_cb(data);
1162 #endif
1163 }
1164
1165 int main(int argc, char *argv[])
1166 {
1167         struct appdata ad;
1168
1169         ui_app_lifecycle_callback_s event_callback = {0,};
1170         app_event_handler_h handlers[5] = {NULL, };
1171
1172         int ret = 0;
1173
1174         _D("Start indicator");
1175
1176         event_callback.create = app_create;
1177         event_callback.terminate = app_terminate;
1178         event_callback.pause = app_pause;
1179         event_callback.resume = app_resume;
1180         event_callback.app_control = app_service;
1181
1182         ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, _indicator_low_bat_cb, NULL);
1183         ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, _indicator_lang_changed_cb, &ad);
1184         ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, _indicator_region_changed_cb, NULL);
1185
1186         memset(&ad, 0x0, sizeof(struct appdata));
1187
1188         ret = ui_app_main(argc, argv, &event_callback, &ad);
1189         if (ret != APP_ERROR_NONE) {
1190                 _E("app_main() is failed. err = %d", ret);
1191         }
1192
1193         return ret;
1194 }
1195
1196 /* End of file */