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