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