Fix coverity issue 1149129
[apps/native/volume-app.git] / src / view.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <Ecore.h>
18 #include <feedback.h>
19 #include <vconf.h>
20 #include <vconf-keys.h>
21 #include <app.h>
22
23 #include "main.h"
24 #include "_util_efl.h"
25 #include "_util_log.h"
26 #include "view.h"
27 #include "control.h"
28 #include "timer.h"
29 #include "key_event.h"
30 #include "sound.h"
31 #include "tzsh_volume_service.h"
32
33 struct _view_s_info {
34         Evas_Object *win;
35         tzsh_h tzsh;
36         tzsh_volume_service_h volume_service;
37         Evas_Object *evas;
38         Evas_Object *ly_outer;
39         Evas_Object *icon_volume;
40         Evas_Object *icon_setting;
41         Evas_Object *slider;
42         Evas_Object *warning_popup;
43         Evas_Object *ao_volume;
44
45         Evas_Object *lockscreen_splash;
46
47         Evas_Object *ao_settings;
48
49         Eina_Bool is_registered_callback;
50         Eina_Bool is_slider_touching;
51         Eina_Bool is_warning_displayed;
52         sound_type_e pre_sound_type;
53 };
54 static struct _view_s_info view_info = {
55         .win = NULL,
56         .tzsh = NULL,
57         .volume_service = NULL,
58         .evas = NULL,
59         .ly_outer = NULL,
60         .icon_volume = NULL,
61         .icon_setting = NULL,
62         .slider = NULL,
63         .warning_popup = NULL,
64         .ao_volume = NULL,
65
66         .lockscreen_splash = NULL,
67
68         .ao_settings = NULL,
69
70         .is_registered_callback = EINA_FALSE,
71         .is_slider_touching = EINA_FALSE,
72         .is_warning_displayed = EINA_FALSE,
73         .pre_sound_type = SOUND_TYPE_RINGTONE
74 };
75
76 static void _button_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
77 static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
78 static void _app_control_error_check(int ret);
79 static void _hide_launcher(void *data, Evas_Object *obj, const char *emission, const char *source);
80 static void _slider_stop_cb(void *data, Evas_Object *obj, void *event_info);
81 static void _slider_start_cb(void *data, Evas_Object *obj, void *event_info);
82 static void _slider_changed_cb(void *data, Evas_Object *obj, void *event_info);
83 static Evas_Object* _slider_make();
84 static Evas_Object* _volume_icon_make();
85 static Evas_Object* _setting_icon_make();
86
87 const char *volume_view_get_file_path(const char *relative)
88 {
89         char *prefix = NULL;
90         static char buf[PATH_MAX];
91
92         prefix = app_get_resource_path();
93
94         if (prefix != NULL) {
95                 size_t res = eina_file_path_join(buf, sizeof(buf), prefix, relative);
96                 snprintf(buf, sizeof(buf), "%s%s", prefix, relative);
97                 free(prefix);
98
99                 if (res > sizeof(buf)) {
100                         _E("Path exceeded PATH_MAX\n");
101                         return NULL;
102                 }
103         }
104         return &buf[0];
105 }
106
107 Evas_Object* volume_view_win_get(void)
108 {
109         return view_info.win;
110 }
111
112 tzsh_h volume_view_tzsh_get(void)
113 {
114         return view_info.tzsh;
115 }
116
117 tzsh_volume_service_h volume_view_service_get(void)
118 {
119         return view_info.volume_service;
120 }
121
122 Evas_Object* volume_view_evas_get(void)
123 {
124         return view_info.evas;
125 }
126
127 Evas_Object* volume_view_outer_layout_get(void)
128 {
129         return view_info.ly_outer;
130 }
131
132 Evas_Object* volume_view_icon_volume_get(void)
133 {
134         return view_info.icon_volume;
135 }
136
137 Evas_Object* volume_view_icon_setting_get(void)
138 {
139         return view_info.icon_setting;
140 }
141
142 Evas_Object* volume_view_slider_get(void)
143 {
144         return view_info.slider;
145 }
146
147 Evas_Object* volume_view_warning_popup_get(void)
148 {
149         return view_info.warning_popup;
150 }
151
152 Eina_Bool volume_view_is_registered_callback_get(void)
153 {
154         return view_info.is_registered_callback;
155 }
156
157 Eina_Bool volume_view_is_slider_touching_get(void)
158 {
159         return view_info.is_slider_touching;
160 }
161
162 sound_type_e volume_view_pre_sound_type_get(void)
163 {
164         return view_info.pre_sound_type;
165 }
166
167 volume_error_e volume_view_set_default_slider()
168 {
169         Evas_Object *slider = volume_view_slider_get();
170         elm_object_style_set(slider, "default");
171         return VOLUME_ERROR_OK;
172 }
173
174 volume_error_e volume_view_set_warning_slider()
175 {
176         Evas_Object *slider = volume_view_slider_get();
177         elm_object_style_set(slider, "warning");
178         Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
179         msg->count = 1;
180         msg->val[0] = 0.66;
181         edje_object_message_send(elm_layout_edje_get(slider), EDJE_MESSAGE_FLOAT_SET, 0, msg);
182
183         return VOLUME_ERROR_OK;
184 }
185
186 int volume_mute_toggle_set()
187 {
188         sound_type_e sound_type = volume_control_get_sound_type_at_show();
189         _D("sound type at show : %d", sound_type);
190
191         int sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
192         _D("sound status : %d", sound);
193
194         int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
195         _E("vibration : %d", vibration);
196
197         if (sound == 1 || vibration == 1) {
198                 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
199                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
200
201                 if (VOLUME_ERROR_OK != volume_view_slider_value_set(0))
202                         _E("Failed to set slider value");
203
204                 return 0;
205         } else {
206                 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
207                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
208
209                 int val = volume_sound_level_get(sound_type);
210                 retv_if(val == -1, 0);
211
212                 if (val == 0) {
213                         if (VOLUME_ERROR_OK != volume_view_slider_value_set(1))
214                                 _E("Failed to set slider value");
215                         volume_sound_level_set(sound_type, 1);
216                 } else {
217                         if (VOLUME_ERROR_OK != volume_view_slider_value_set(val))
218                                 _E("Failed to set slider value");
219                 }
220
221                 return 1;
222         }
223 }
224
225 volume_error_e volume_view_change_slider_by_type(sound_type_e type, bool bt_opened, int earphone_connected)
226 {
227         _D("Slider change for state: %d", type);
228         int ret = 0;
229         int step = 0;
230
231         if (type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected)) {
232                 _D("=Change to warning slider=");
233                 elm_object_style_set(view_info.slider, "warning");
234         } else {
235                 _D("=Change to normal slider=");
236                 elm_object_style_set(view_info.slider, "default");
237         }
238
239         ret = sound_manager_get_max_volume(type, &step);
240         if (ret < 0) {
241                 _E("Failed to get max volume for sound_type: %d", type);
242                 return VOLUME_ERROR_FAIL;
243         }
244         _D("Sound type: %d, max: %d", type, step);
245
246         elm_slider_min_max_set(view_info.slider, 0, step);
247
248         view_info.pre_sound_type = type;
249
250         return VOLUME_ERROR_OK;
251 }
252
253 static void _cancel_clicked_cb(void *data, Evas_Object *obj, void *event_info)
254 {
255         volume_view_destroy_warning_popup();
256 }
257
258 static void _ok_clicked_cb(void *data, Evas_Object *obj, void *event_info)
259 {
260         _D("Increase button is clicked");
261         volume_control_set_safety_limit(EINA_FALSE);
262         volume_control_set_time_for_safety_limit();
263
264         volume_view_destroy_warning_popup();
265 }
266
267 volume_error_e volume_view_open_warning_popup(void)
268 {
269         Evas_Object *popup = NULL;
270         Evas_Object *cancel_btn = NULL;
271         Evas_Object *ok_btn = NULL;
272
273         popup = elm_popup_add(view_info.win);
274         elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
275         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
276         elm_object_text_set(popup, "Listening at a high volume for a long time may damage your hearing. The volume will be increaed above safe levels.");
277
278         cancel_btn = elm_button_add(popup);
279         elm_object_style_set(cancel_btn, "popup");
280         elm_object_text_set(cancel_btn, "Cancel");
281         elm_object_part_content_set(popup, "button2", cancel_btn);
282         evas_object_smart_callback_add(cancel_btn, "clicked", _cancel_clicked_cb, popup);
283
284         ok_btn = elm_button_add(popup);
285         elm_object_style_set(ok_btn, "popup");
286         elm_object_text_set(ok_btn, "Increase");
287         elm_object_part_content_set(popup, "button1", ok_btn);
288         evas_object_smart_callback_add(ok_btn, "clicked", _ok_clicked_cb, popup);
289
290         view_info.warning_popup = popup;
291         evas_object_show(popup);
292
293         return VOLUME_ERROR_OK;
294 }
295
296 void volume_view_destroy_warning_popup(void)
297 {
298         _D("Destroy warning popup");
299         if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_FALSE))
300                 _E("Failed to set warning status");
301
302         evas_object_del(view_info.warning_popup);
303         view_info.warning_popup = NULL;
304
305         if (VOLUME_ERROR_OK != volume_control_hide_view())
306                 _E("Failed to close volume");
307         if (VOLUME_ERROR_OK != volume_control_cache_flush())
308                 _E("Failed to flush cache");
309 }
310
311 volume_error_e volume_view_slider_value_set(int val)
312 {
313         _D("Slider value set : %d", val);
314         retv_if(view_info.is_slider_touching, VOLUME_ERROR_FAIL);
315         retv_if(val < 0, VOLUME_ERROR_FAIL);
316
317         elm_slider_value_set(view_info.slider, val);
318
319         return VOLUME_ERROR_OK;
320 }
321
322 void volume_view_volume_icon_set(sound_type_e sound_type, int sound, int vibration, bool bt_opened)
323 {
324         _D("Volume icon set");
325         char *img = NULL;
326
327         if (sound == -1 || vibration == -1) {
328                 img = IMG_VOLUME_ICON_MUTE;
329                 _D("img : %s", img);
330                 elm_image_file_set(view_info.icon_volume, volume_view_get_file_path(EDJ_APP), img);
331                 return;
332         }
333
334         switch (sound_type) {
335         case SOUND_TYPE_ALARM:
336         case SOUND_TYPE_RINGTONE:
337                 if (sound)
338                         img = IMG_VOLUME_ICON;
339                 else if (vibration)
340                         img = IMG_VOLUME_ICON_VIB;
341                 else
342                         img = IMG_VOLUME_ICON_MUTE;
343                 break;
344         case SOUND_TYPE_MEDIA:
345                 if (volume_sound_sound_manager_volume_get(sound_type) > 0)
346                         img = IMG_VOLUME_ICON;
347                 else
348                         img = IMG_VOLUME_ICON_MUTE;
349                 break;
350         case SOUND_TYPE_CALL:
351                 if (bt_opened)
352                         img = IMG_VOLUME_ICON_HEADPHONE;
353                 else
354                         img = IMG_VOLUME_ICON_CALL;
355                 break;
356         case SOUND_TYPE_NOTIFICATION:
357                 if (sound)
358                         img = IMG_VOLUME_ICON_NOTI;
359                 else if (vibration)
360                         img = IMG_VOLUME_ICON_NOTI_VIB;
361                 else
362                         img = IMG_VOLUME_ICON_NOTI_MUTE;
363                 break;
364         default:
365                 img = IMG_VOLUME_ICON;
366                 break;
367         }
368
369         _D("img : %s", img);
370         elm_image_file_set(view_info.icon_volume, volume_view_get_file_path(EDJ_APP), img);
371 }
372
373 void volume_view_volume_icon_name_set_for_access(sound_type_e sound_type)
374 {
375         _D("Volume icon name set");
376         char buf[2056];
377
378         switch (sound_type) {
379         case SOUND_TYPE_RINGTONE:
380                 snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_HEADER_RINGTONES"), "volume");
381                 break;
382         case SOUND_TYPE_MEDIA:
383                 snprintf(buf, sizeof(buf), "%s", _("IDS_ACCS_BODY_MEDIA_VOLUME_TTS"));
384                 break;
385         case SOUND_TYPE_CALL:
386                 snprintf(buf, sizeof(buf), "%s%s", _("IDS_ACCS_SK2_CALL"), "volume");
387                 break;
388         case SOUND_TYPE_NOTIFICATION:
389                 snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_BODY_NOTIFICATION"), "volume");
390                 break;
391         default:
392                 snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_HEADER_RINGTONES"), "volume");
393                 break;
394         }
395
396         _D("volume accessible name: %s", buf);
397         elm_atspi_accessible_name_set(view_info.ao_volume, buf);
398 }
399
400 void volume_view_setting_icon_set(const char *file)
401 {
402         _D("Setting icon image set");
403         ret_if(!file);
404
405         Evas_Object *icon_setting = view_info.icon_setting;
406         ret_if(!icon_setting);
407
408         if (EINA_TRUE != elm_image_file_set(icon_setting, volume_view_get_file_path(EDJ_APP), file)) {
409                 _E("Failed to set image file : %s, Group", file);
410         };
411 }
412
413 void volume_view_setting_icon_callback_add(void)
414 {
415         _D("Setting callback add");
416         ret_if(view_info.is_registered_callback);
417
418         Evas_Object *icon_setting = view_info.icon_setting;
419         ret_if(!icon_setting);
420
421         evas_object_event_callback_add(icon_setting, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb, NULL);
422         elm_object_signal_callback_add(view_info.ly_outer, "setting_icon_touched", "launch_setting", _button_cb, NULL);
423
424         view_info.is_registered_callback = EINA_TRUE;
425 }
426
427 void volume_view_setting_icon_callback_del(void)
428 {
429         _D("Setting callback del");
430         ret_if(!view_info.is_registered_callback);
431
432         Evas_Object *icon_setting = view_info.icon_setting;
433         ret_if(!icon_setting);
434
435         elm_object_signal_callback_del(view_info.ly_outer, "setting_icon_touched", "launch_setting", _button_cb);
436         evas_object_event_callback_del(icon_setting, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb);
437
438         view_info.is_registered_callback = EINA_FALSE;
439 }
440
441 Evas_Object *add_slider(Evas_Object *parent, int min, int max, int val)
442 {
443         retv_if(!parent, NULL);
444         Evas_Object *slider = elm_slider_add(parent);
445         retvm_if(!slider, NULL, "Failed to add slider");
446
447         elm_slider_horizontal_set(slider, EINA_TRUE);
448         elm_slider_indicator_show_set(slider, EINA_FALSE);
449         elm_slider_indicator_format_set(slider, "%.0f");
450         evas_object_size_hint_weight_set(slider, EVAS_HINT_EXPAND, 0.0);
451         evas_object_size_hint_align_set(slider, EVAS_HINT_FILL, 0.5);
452         elm_slider_min_max_set(slider, min, max);
453         elm_slider_value_set(slider, val);
454
455         return slider;
456 }
457
458 volume_error_e volume_view_send_warning_signal(Eina_Bool warning)
459 {
460         if (warning) {
461                 _D("Show warning popup, and hide volume popup");
462                 elm_object_signal_emit(view_info.ly_outer, "show,warning", "bg");
463         } else {
464                 int current_angle = volume_control_get_current_angle();
465                 _D("Current angle: %d", current_angle);
466                 switch (current_angle) {
467                 case 90:
468                 case 270:
469                         _D("show,landscape");
470                         elm_object_signal_emit(view_info.ly_outer, "show,landscape", "bg");
471                         break;
472                 default:
473                         _D("show,portrait");
474                         elm_object_signal_emit(view_info.ly_outer, "show,portrait", "bg");
475                         break;
476                 }
477         }
478         return VOLUME_ERROR_OK;
479 }
480
481 volume_error_e volume_view_window_show(sound_type_e type)
482 {
483         _D("Volume view window SHOW is [%p]", view_info.win);
484
485         elm_win_activate(view_info.win);
486
487         if (type == SOUND_TYPE_CALL)
488                 _D("Sound type is Call");
489         else
490                 volume_view_setting_icon_callback_add();
491
492         return VOLUME_ERROR_OK;
493 }
494
495 volume_error_e volume_view_window_hide(void)
496 {
497         _D("Volume view window HIDE");
498         elm_win_iconified_set(view_info.win, EINA_TRUE);
499         volume_view_setting_icon_callback_del();
500
501         return VOLUME_ERROR_OK;
502 }
503
504 Evas_Object *add_layout(Evas_Object *parent, const char *file, const char *group)
505 {
506         retvm_if(!parent, NULL, "Invalid argument: parent is NULL\n");
507         retvm_if(!file, NULL, "Invalid argument: file is NULL\n");
508         retvm_if(!group, NULL, "Invalid argument: group is NULL\n");
509
510         Evas_Object *eo = elm_layout_add(parent);
511         retvm_if(!eo, NULL, "Failed to add layout\n");
512
513         int r = -1;
514         r = elm_layout_file_set(eo, file, group);
515         if (!r) {
516                 _E("Failed to set file[%s]\n", file);
517                 evas_object_del(eo);
518                 return NULL;
519         }
520
521         evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
522         evas_object_show(eo);
523
524         return eo;
525 }
526
527 void _connect_to_wm(Evas_Object *win)
528 {
529         _D("Make connection with window manager");
530         tzsh_window tz_win;
531
532         view_info.tzsh = tzsh_create(TZSH_TOOLKIT_TYPE_EFL);
533         if (!view_info.tzsh)
534                 _E("Failed to get connection to Tizen window manager");
535
536         tz_win = elm_win_window_id_get(win);
537         if (!tz_win)
538                 _E("Failed to get Tizen window manager");
539
540         /*
541          * Tizen SDK do not support tzsh yet
542          * If you want to build with ABS you should Block this code
543          */
544 #if 0
545         view_info.volume_service = tzsh_volume_service_create(view_info.tzsh, tz_win);
546         if (!view_info.volume_service)
547                 _E("Failed to get volume service");
548 #endif
549 }
550
551 static void _down_for_hide(void *data, Evas_Object *obj, const char* emission, const char* source)
552 {
553         _D("Down for HIDE");
554
555         if (VOLUME_ERROR_OK != volume_control_hide_view())
556                 _E("Failed to close volume");
557 }
558
559 volume_error_e volume_view_layout_create(Evas_Object *win)
560 {
561         _D("Layout create");
562
563         retv_if(!win, VOLUME_ERROR_FAIL);
564
565         Evas_Object *ly_outer = add_layout(win, volume_view_get_file_path(EDJ_APP), "volume_layout");
566         retv_if(!ly_outer, VOLUME_ERROR_FAIL);
567         elm_win_resize_object_add(win, ly_outer);
568         elm_object_signal_callback_add(ly_outer, "hide,popup", "event", _hide_launcher, NULL);
569         view_info.ly_outer = ly_outer;
570
571         /* make setting icon */
572         Evas_Object *icon_setting = _setting_icon_make();
573         retv_if(!icon_setting, VOLUME_ERROR_FAIL);
574         elm_object_part_content_set(ly_outer, "ic_setting", icon_setting);
575         view_info.icon_setting = icon_setting;
576
577         /* make volume icon */
578         Evas_Object *icon_volume = _volume_icon_make();
579         retv_if(!icon_volume, VOLUME_ERROR_FAIL);
580         elm_object_part_content_set(ly_outer, "ic_sound", icon_volume);
581         view_info.icon_volume = icon_volume;
582
583         /* make slider */
584         Evas_Object *slider = _slider_make();
585         retv_if(!slider, VOLUME_ERROR_FAIL);
586         view_info.slider = slider;
587         elm_object_part_content_set(ly_outer, "sw.slider", slider);
588
589         /* add callback for hide */
590         elm_object_signal_callback_add(ly_outer, "hide,volume", "hide", _down_for_hide, NULL);
591
592         return VOLUME_ERROR_OK;
593 }
594
595 static void _iconified_cb(void *data, Evas_Object *obj, void *event_info)
596 {
597         _D("ICONIFIED IS CALLED");
598 }
599
600 static void _deiconified_cb(void *data, Evas_Object *obj, void *event_info)
601 {
602         _D("ICONIFIED IS CANCELED");
603 }
604
605 Evas_Object *add_volume_window(const char *name)
606 {
607         Evas_Object *eo = NULL;
608         Evas *evas = NULL;
609         int x, y, w, h = 0;
610
611         eo = elm_win_add(NULL, name, ELM_WIN_NOTIFICATION);
612         retv_if(!eo, NULL);
613         evas = evas_object_evas_get(eo);
614         retv_if(!evas, NULL);
615         view_info.evas = evas;
616
617         elm_win_alpha_set(eo, EINA_TRUE);
618         elm_win_title_set(eo, name);
619         elm_win_borderless_set(eo, EINA_TRUE);
620         ecore_evas_name_class_set(ecore_evas_ecore_evas_get(evas), "SYSTEM_POPUP", "SYSTEM_POPUP");
621         elm_win_prop_focus_skip_set(eo, EINA_TRUE);
622         elm_win_role_set(eo, "no-dim");
623
624         elm_win_screen_size_get(eo, &x, &y, &w, &h);
625         _D("volume screen size => x: %d, y: %d, w: %d, h: %d", x, y, w, h);
626
627         evas_object_smart_callback_add(eo, "iconified", _iconified_cb, NULL);
628         evas_object_smart_callback_add(eo, "normal", _deiconified_cb, NULL);
629
630         return eo;
631 }
632
633 static Eina_Bool _key_grab_cb(void *data)
634 {
635         int ret_up = 0;
636         int ret_down = 0;
637         Evas_Object *win = data;
638
639         _D("keygrab window is [%p]", win);
640         ret_up = elm_win_keygrab_set(win, KEY_VOLUMEUP, 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
641         _D("Result of volume up keygrab set : %d", ret_up);
642         ret_down = elm_win_keygrab_set(win, KEY_VOLUMEDOWN, 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
643         _D("Result of volume down keygrab set : %d", ret_down);
644
645         return EINA_FALSE;
646 }
647
648 Evas_Object *volume_view_window_create(void)
649 {
650         Evas_Object *win = add_volume_window(PACKAGE);
651         retv_if(!win, NULL);
652
653         view_info.win = win;
654
655         evas_object_show(win);
656
657         ecore_timer_add(1.0f, _key_grab_cb, win);
658
659         _connect_to_wm(win);
660
661         elm_win_iconified_set(win, EINA_TRUE);
662
663         return win;
664 }
665
666 void _lock_sound_check(void)
667 {
668         int lcdoff_source = -1;
669         int lock_sound = -1;
670         int lock_type = -1;
671
672         if (vconf_get_int(VCONFKEY_PM_LCDOFF_SOURCE, &lcdoff_source) < 0) {
673                 _E("Failed to get vconfkey : VCONFKEY_PM_LCDOFF_SOURCE");
674                 return;
675         }
676         _D("lcd off source : %d", lcdoff_source);
677
678         if (lcdoff_source != VCONFKEY_PM_LCDOFF_BY_POWERKEY) {
679                 _E("Should not play lock sound");
680                 return;
681         }
682
683         if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, &lock_sound) < 0) {
684                 _E("Failed to get vconfkey : VCONFKEY_SETAPPL_SOUND_LOCK_BOOL");
685                 return;
686         }
687         _D("lock sound : %d", lock_sound);
688
689         if (lock_sound) {
690                 if (vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &lock_type) < 0) {
691                         _E("Failed to get vconfkey : VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT");
692                         lock_type = 0;
693                 }
694                 _D("lock type : %d", lock_type);
695
696                 if (FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_LOCK)) {
697                         _E("Failed to play vibration");
698                 }
699         }
700 }
701
702 Evas_Object* show_lockscreen_splash(const char* bg_path)
703 {
704         _D(" ");
705
706         retv_if(bg_path == NULL, NULL);
707
708         if (view_info.lockscreen_splash) {
709                 _E("There is remain fake_bg : remove old one");
710                 evas_object_del(view_info.lockscreen_splash);
711                 view_info.lockscreen_splash = NULL;
712         }
713
714         /* Check Lock Sound */
715         _lock_sound_check();
716
717         /* hide volume window */
718         if (VOLUME_ERROR_OK != volume_view_window_hide())
719                 _E("Failed to hide window");
720
721         Evas_Object *win_splash = elm_win_add(NULL, "lockscreen_splash", ELM_WIN_NOTIFICATION);
722
723         if (!win_splash) {
724                 _E("Failed to add splash window");
725                 return NULL;
726         }
727
728         _D("Splash window created");
729
730         Evas_Object *bg = elm_bg_add(win_splash);
731         if (!bg) {
732                 _D("Failed to get background");
733                 evas_object_del(win_splash);
734                 return NULL;
735         }
736
737         elm_win_resize_object_add(win_splash, bg);
738         elm_bg_file_set(bg, bg_path, NULL);
739         evas_object_show(bg);
740
741         evas_object_show(win_splash);
742
743         _D("Splash window shown");
744
745         view_info.lockscreen_splash = win_splash;
746
747         return win_splash;
748 }
749
750 volume_error_e hide_lockscreen_splash(void)
751 {
752         _D(" ");
753
754         if (!view_info.lockscreen_splash) {
755                 _E("No splash window found");
756                 return VOLUME_ERROR_FAIL;
757         }
758
759         evas_object_del(view_info.lockscreen_splash);
760         view_info.lockscreen_splash = NULL;
761         _D("Splash window closed");
762
763         return VOLUME_ERROR_OK;
764 }
765 static void _slider_start_cb(void *data, Evas_Object *obj, void *event_info)
766 {
767         view_info.is_slider_touching = EINA_TRUE;
768
769         volume_timer_del(TYPE_TIMER_POPUP);
770
771         volume_timer_add(0.2, TYPE_TIMER_SLIDER);
772 }
773
774 static void _slider_changed_cb(void *data, Evas_Object *obj, void *event_info)
775 {
776         volume_timer_del(TYPE_TIMER_POPUP);
777
778         double val = 0;
779
780         sound_type_e sound_type = volume_control_get_sound_type_at_show();
781         _D("sound type at show : %d", sound_type);
782
783         val = elm_slider_value_get(view_info.slider);
784         val += 0.5;
785         _D("slider value : %lf", val);
786
787         if (view_info.is_slider_touching)
788                 return;
789
790         volume_sound_change_set((int)val);
791
792         if (!volume_key_event_is_pressing_get()) {
793                 volume_timer_add(3.0, TYPE_TIMER_POPUP);
794                 return;
795         }
796
797         if (!view_info.is_slider_touching) {
798                 volume_timer_add(3.0, TYPE_TIMER_POPUP);
799                 return;
800         }
801 }
802
803 static void _slider_stop_cb(void *data, Evas_Object *obj, void *event_info)
804 {
805         view_info.is_slider_touching = EINA_FALSE;
806
807         volume_timer_del(TYPE_TIMER_SLIDER);
808
809         Evas_Object *slider = volume_view_slider_get();
810         ret_if(slider == NULL);
811
812         double val = 0;
813
814         val = elm_slider_value_get(slider);
815         val += 0.5;
816         _D("slider value : %d", (int)val);
817
818         volume_sound_change_set((int)val);
819
820         volume_timer_add(3.0, TYPE_TIMER_POPUP);
821 }
822
823 static void _hide_launcher(void *data, Evas_Object *obj, const char *emission, const char *source)
824 {
825         evas_object_hide(view_info.win);
826 }
827
828 static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
829 {
830         elm_object_signal_emit(view_info.ly_outer, "pressed", "setting");
831 }
832
833 static void _app_control_error_check(int ret)
834 {
835         if (ret != APP_CONTROL_ERROR_NONE) {
836                 switch (ret) {
837                 case APP_CONTROL_ERROR_INVALID_PARAMETER:
838                         _E("error : APP_CONTROL_ERROR_INVALID_PARAMETER");
839                         break;
840                 case APP_CONTROL_ERROR_OUT_OF_MEMORY:
841                         _E("error : APP_CONTROL_ERROR_OUT_OF_MEMORY");
842                         break;
843                 case APP_CONTROL_ERROR_APP_NOT_FOUND:
844                         _E("error : APP_CONTROL_ERROR_APP_NOT_FOUND");
845                         break;
846                 case APP_CONTROL_ERROR_LAUNCH_REJECTED:
847                         _E("error : APP_CONTROL_ERROR_LAUNCH_REJECTED");
848                         break;
849                 default:
850                         _E("error : %d", ret);
851                         break;
852                 }
853         }
854 }
855
856 static void _button_cb(void *data, Evas_Object *obj, const char *emssion, const char *source)
857 {
858         int ret = -1;
859         app_control_h app_setting;
860
861         if (evas_object_visible_get(view_info.win)) {
862                 volume_timer_del(TYPE_TIMER_POPUP);
863
864                 volume_sound_feedback_play(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_TAP);
865
866                 /* Send Launch Request to Setting */
867                 ret = app_control_create(&app_setting);
868                 _app_control_error_check(ret);
869
870                 ret = app_control_set_app_id(app_setting, "org.tizen.setting.volume");
871                 _app_control_error_check(ret);
872
873                 ret = app_control_send_launch_request(app_setting, NULL, NULL);
874                 _app_control_error_check(ret);
875
876                 if (VOLUME_ERROR_OK != volume_control_pause())
877                         _E("Failed to pause volume");
878
879                 app_control_destroy(app_setting);
880         }
881 }
882
883 static Evas_Object* _setting_icon_make()
884 {
885         _D("Setting ICON make");
886         Evas_Object *icon_setting = elm_icon_add(view_info.ly_outer);
887         retv_if(!icon_setting, NULL);
888
889         evas_object_size_hint_aspect_set(icon_setting, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
890         elm_image_resizable_set(icon_setting, EINA_TRUE, EINA_TRUE);
891
892         view_info.icon_setting = icon_setting;
893
894         volume_view_setting_icon_set(IMG_VOLUME_ICON_SETTINGS);
895         evas_object_show(icon_setting);
896
897         return icon_setting;
898 }
899
900 static Evas_Object* _volume_icon_make()
901 {
902         Evas_Object *icon_volume = elm_icon_add(view_info.ly_outer);
903         retv_if(!icon_volume, NULL);
904
905         evas_object_size_hint_aspect_set(icon_volume, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
906         elm_image_resizable_set(icon_volume, EINA_TRUE, EINA_TRUE);
907         evas_object_show(icon_volume);
908
909         return icon_volume;
910 }
911
912 static Evas_Object* _slider_make()
913 {
914         _D("Volume Slider Make");
915         sound_type_e sound_type = volume_control_get_sound_type_at_show();
916         _D("sound type at show : %d", sound_type);
917
918         int sound_step = volume_sound_sound_manager_step_get(sound_type);
919         _D("sound step : %d", sound_step);
920
921         int sound_val = volume_sound_level_get(sound_type);
922         if (sound_val == -1) {
923                 _E("Failed to get volume level");
924                 sound_val = 0;
925         }
926         _D("sound value : %d", sound_val);
927
928         Evas_Object *slider = add_slider(view_info.ly_outer, 0, sound_step, sound_val);
929         retv_if(!slider, NULL);
930         evas_object_smart_callback_add(slider, "slider,drag,start", _slider_start_cb, NULL);
931         evas_object_smart_callback_add(slider, "changed", _slider_changed_cb, NULL);
932         evas_object_smart_callback_add(slider, "slider,drag,stop", _slider_stop_cb, NULL);
933
934         return slider;
935 }
936
937 static Eina_Bool _access_highlight_cb(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info)
938 {
939         volume_timer_del(TYPE_TIMER_POPUP);
940         volume_timer_add(3.0, TYPE_TIMER_POPUP);
941
942         return EINA_FALSE;
943 }
944
945 static Eina_Bool _access_active_cb(void *data, Evas_Object *obj, Elm_Access_Action_Info *action_info)
946 {
947         _button_cb(NULL, NULL, NULL, NULL);
948         return EINA_FALSE;
949 }
950
951 void volume_view_accessible_create(Evas_Object *win)
952 {
953         Evas_Object *ao_setting = NULL;
954         char buf[2056];
955
956         /* make volume accessible icon */
957         view_info.ao_volume = elm_access_object_register(view_info.icon_volume, view_info.icon_volume);
958         elm_atspi_accessible_reading_info_type_set(view_info.ao_volume, ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
959         elm_atspi_accessible_translation_domain_set(view_info.ao_volume, PACKAGE);
960         elm_access_action_cb_set(view_info.ao_volume, ELM_ACCESS_ACTION_HIGHLIGHT, _access_highlight_cb, NULL);
961
962         /* make setting accessible icon */
963         ao_setting = elm_access_object_register(view_info.icon_setting, view_info.icon_setting);
964         snprintf(buf, sizeof(buf), "%s%s", _("IDS_ST_BUTTON_SETTINGS"), "button");
965         elm_atspi_accessible_name_set(ao_setting, buf);
966         elm_atspi_accessible_reading_info_type_set(ao_setting, ELM_ACCESSIBLE_READING_INFO_TYPE_NAME);
967         elm_atspi_accessible_translation_domain_set(ao_setting, PACKAGE);
968         elm_access_action_cb_set(ao_setting, ELM_ACCESS_ACTION_HIGHLIGHT, _access_highlight_cb, NULL);
969         elm_access_action_cb_set(ao_setting, ELM_ACCESS_ACTION_ACTIVATE, _access_active_cb, NULL);
970
971         /* Make relationship */
972         elm_atspi_accessible_relationship_append(view_info.ao_volume, ELM_ATSPI_RELATION_FLOWS_TO, view_info.slider);
973         elm_atspi_accessible_relationship_append(view_info.slider, ELM_ATSPI_RELATION_FLOWS_FROM, view_info.ao_volume);
974
975         elm_atspi_accessible_relationship_append(view_info.slider, ELM_ATSPI_RELATION_FLOWS_TO, ao_setting);
976         elm_atspi_accessible_relationship_append(ao_setting, ELM_ATSPI_RELATION_FLOWS_FROM, view_info.slider);
977 }
978