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