2 * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <vconf-keys.h>
23 #include "_util_efl.h"
24 #include "_util_log.h"
28 #include "key_event.h"
30 #include "tzsh_volume_service.h"
35 tzsh_volume_service_h volume_service;
37 Evas_Object *ly_outer;
38 Evas_Object *icon_volume;
39 Evas_Object *icon_setting;
42 Evas_Object *lockscreen_splash;
44 Evas_Object *ao_settings;
46 Eina_Bool is_registered_callback;
47 Eina_Bool is_slider_touching;
48 Eina_Bool is_warning_displayed;
49 sound_type_e pre_sound_type;
51 static struct _view_s_info view_info = {
54 .volume_service = NULL,
61 .lockscreen_splash = NULL,
65 .is_registered_callback = EINA_FALSE,
66 .is_slider_touching = EINA_FALSE,
67 .is_warning_displayed = EINA_FALSE,
68 .pre_sound_type = SOUND_TYPE_RINGTONE
71 static void _button_cb(void *data, Evas_Object *obj, void *event_info);
72 static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
73 static void _app_control_error_check(int ret);
74 static void _hide_launcher(void *data, Evas_Object *obj, const char *emission, const char *source);
75 static void _slider_stop_cb(void *data, Evas_Object *obj, void *event_info);
76 static void _slider_start_cb(void *data, Evas_Object *obj, void *event_info);
77 static void _slider_changed_cb(void *data, Evas_Object *obj, void *event_info);
78 static Evas_Object* _slider_make();
79 static Evas_Object* _volume_icon_make();
80 static Evas_Object* _setting_icon_make();
82 Evas_Object* volume_view_win_get(void)
87 tzsh_h volume_view_tzsh_get(void)
89 return view_info.tzsh;
92 tzsh_volume_service_h volume_view_service_get(void)
94 return view_info.volume_service;
97 Evas_Object* volume_view_evas_get(void)
99 return view_info.evas;
102 Evas_Object* volume_view_outer_layout_get(void)
104 return view_info.ly_outer;
107 Evas_Object* volume_view_icon_volume_get(void)
109 return view_info.icon_volume;
112 Evas_Object* volume_view_icon_setting_get(void)
114 return view_info.icon_setting;
117 Evas_Object* volume_view_slider_get(void)
119 return view_info.slider;
122 Eina_Bool volume_view_is_registered_callback_get(void)
124 return view_info.is_registered_callback;
127 Eina_Bool volume_view_is_slider_touching_get(void)
129 return view_info.is_slider_touching;
132 sound_type_e volume_view_pre_sound_type_get(void)
134 return view_info.pre_sound_type;
137 volume_error_e volume_view_set_default_slider(){
138 Evas_Object *slider = volume_view_slider_get();
139 elm_object_style_set(slider, "default");
140 return VOLUME_ERROR_OK;
143 volume_error_e volume_view_set_warning_slider(){
144 Evas_Object *slider = volume_view_slider_get();
145 elm_object_style_set(slider, "warning");
146 Edje_Message_Float_Set *msg = alloca(sizeof(Edje_Message_Float_Set) + (sizeof(double)));
149 edje_object_message_send(elm_layout_edje_get(slider), EDJE_MESSAGE_FLOAT_SET, 0, msg);
151 return VOLUME_ERROR_OK;
154 int volume_mute_toggle_set()
156 sound_type_e sound_type = volume_control_get_sound_type_at_show();
157 _D("sound type at show : %d", sound_type);
159 int sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
160 _D("sound status : %d", sound);
162 int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
163 _E("vibration : %d", vibration);
165 if (sound == 1 || vibration == 1) {
166 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
167 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
169 if(VOLUME_ERROR_OK != volume_view_slider_value_set(0))
170 _E("Failed to set slider value");
175 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
176 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
178 int val = volume_sound_level_get(sound_type);
179 retv_if(val == -1, 0);
182 if (VOLUME_ERROR_OK != volume_view_slider_value_set(1))
183 _E("Failed to set slider value");
184 volume_sound_level_set(sound_type, 1);
186 if (VOLUME_ERROR_OK != volume_view_slider_value_set(val))
187 _E("Failed to set slider value");
194 volume_error_e volume_change_slider_max_value(sound_type_e type)
196 _D("Slider max change for state: %d", type);
200 ret = sound_manager_get_max_volume(type, &step);
202 _E("Failed to get max volume for sound_type: %d", type);
203 return VOLUME_ERROR_FAIL;
205 _D("Sound type: %d, max: %d", type, step);
207 elm_slider_min_max_set(view_info.slider, 0, step);
209 view_info.pre_sound_type = type;
211 return VOLUME_ERROR_OK;
214 volume_error_e volume_view_slider_value_set(int val)
216 _D("Slider value set : %d", val);
217 retv_if(view_info.is_slider_touching, VOLUME_ERROR_FAIL);
218 retv_if(val<0, VOLUME_ERROR_FAIL);
220 elm_slider_value_set(view_info.slider, val);
222 return VOLUME_ERROR_OK;
225 void volume_view_volume_icon_set(sound_type_e sound_type, int sound, int vibration, bool bt_opened)
227 _D("Volume icon set");
230 if (sound == -1 || vibration == -1) {
231 img = IMG_VOLUME_ICON_MUTE;
233 elm_image_file_set(view_info.icon_volume, EDJ_APP, img);
239 case SOUND_TYPE_RINGTONE:
241 img = IMG_VOLUME_ICON;
243 img = IMG_VOLUME_ICON_VIB;
245 img = IMG_VOLUME_ICON_MUTE;
247 case SOUND_TYPE_MEDIA:
248 img = IMG_VOLUME_ICON_MEDIA;
250 case SOUND_TYPE_CALL:
252 img = IMG_VOLUME_ICON_CALL;
254 img = IMG_VOLUME_ICON_CALL;
256 case SOUND_TYPE_NOTIFICATION:
258 img = IMG_VOLUME_ICON_NOTI;
260 img = IMG_VOLUME_ICON_NOTI_VIB;
262 img = IMG_VOLUME_ICON_NOTI_MUTE;
264 case SOUND_TYPE_ALARM:
265 img = IMG_VOLUME_ICON_MEDIA;
268 img = IMG_VOLUME_ICON;
272 volume_view_set_default_slider();
275 elm_image_file_set(view_info.icon_volume, EDJ_APP, img);
278 void volume_view_setting_icon_set(const char *file)
280 _D("Setting icon image set");
283 Evas_Object *icon_setting = view_info.icon_setting;
284 ret_if(!icon_setting);
286 if (EINA_TRUE != elm_image_file_set(icon_setting, EDJ_APP, file)) {
287 _E("Failed to set image file : %s, Group", EDJ_APP, file);
291 void volume_view_setting_icon_callback_add(void)
293 _D("Setting callback add");
294 ret_if(view_info.is_registered_callback);
296 Evas_Object *icon_setting = view_info.icon_setting;
297 ret_if(!icon_setting);
299 evas_object_event_callback_add(icon_setting, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb, NULL);
300 evas_object_smart_callback_add(icon_setting, "clicked", _button_cb, NULL);
302 view_info.is_registered_callback = EINA_TRUE;
305 void volume_view_setting_icon_callback_del(void)
307 _D("Setting callback del");
308 ret_if(!view_info.is_registered_callback);
310 Evas_Object *icon_setting = view_info.icon_setting;
311 ret_if(!icon_setting);
313 evas_object_smart_callback_del(icon_setting, "clicked", _button_cb );
314 evas_object_event_callback_del(icon_setting, EVAS_CALLBACK_MOUSE_DOWN, _button_mouse_down_cb);
316 view_info.is_registered_callback = EINA_FALSE;
319 Evas_Object *add_slider(Evas_Object *parent, int min, int max, int val)
321 retv_if(!parent, NULL);
322 Evas_Object *slider = elm_slider_add(parent);
323 retvm_if(!slider, NULL, "Failed to add slider");
325 elm_slider_horizontal_set(slider, EINA_TRUE);
326 elm_slider_indicator_show_set(slider, EINA_FALSE);
327 elm_slider_indicator_format_set(slider, "%.0f");
328 evas_object_size_hint_weight_set(slider, EVAS_HINT_EXPAND, 0.0);
329 evas_object_size_hint_align_set(slider, EVAS_HINT_FILL, 0.5);
330 elm_slider_min_max_set(slider, min, max);
331 elm_slider_value_set(slider, val);
336 volume_error_e volume_view_window_show(sound_type_e type)
338 _D("Volume view window SHOW is [%p]", view_info.win);
340 elm_win_iconified_set(view_info.win, EINA_FALSE);
342 if (type == SOUND_TYPE_CALL) {
343 _D("Sound type is Call");
345 volume_view_setting_icon_callback_add();
348 return VOLUME_ERROR_OK;
351 volume_error_e volume_view_window_hide(void)
353 _D("Volume view window HIDE");
354 elm_win_iconified_set(view_info.win, EINA_TRUE);
355 volume_view_setting_icon_callback_del();
357 return VOLUME_ERROR_OK;
360 Evas_Object *add_layout(Evas_Object *parent, const char *file, const char *group)
362 retvm_if(!parent, NULL, "Invalid argument: parent is NULL\n");
363 retvm_if(!file, NULL, "Invalid argument: file is NULL\n");
364 retvm_if(!group, NULL, "Invalid argument: group is NULL\n");
366 Evas_Object *eo = elm_layout_add(parent);
367 retvm_if(!eo, NULL, "Failed to add layout\n");
370 r = elm_layout_file_set(eo, file, group);
372 _E("Failed to set file[%s]\n", file);
377 evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
378 evas_object_show(eo);
383 void _connect_to_wm(Evas_Object *win)
385 _D("Mack connection with window manager");
389 view_info.tzsh = tzsh_create(TZSH_TOOLKIT_TYPE_EFL);
390 if (!view_info.tzsh) {
391 _E("Failed to get connection to Tizen window manager");
394 tz_win = elm_win_window_id_get(win);
396 _E("Failed to get Tizen window manager");
399 view_info.volume_service = tzsh_volume_service_create(view_info.tzsh, tz_win);
400 if (!view_info.volume_service) {
401 _E("Failed to get volume service");
405 static void _down_for_hide(void *data, Evas_Object *obj, const char* emission, const char* source)
407 LOGD("Down for HIDE");
409 volume_control_hide_view();
412 volume_error_e volume_view_layout_create(Evas_Object *win)
414 LOGD("Layout create");
416 retv_if(!win, VOLUME_ERROR_FAIL);
418 Evas_Object *ly_outer = add_layout(win, EDJ_APP, "volume_layout");
419 retv_if(!ly_outer, VOLUME_ERROR_FAIL);
420 elm_win_resize_object_add(win, ly_outer);
421 elm_object_signal_callback_add(ly_outer, "hide,popup", "event", _hide_launcher, NULL);
422 view_info.ly_outer = ly_outer;
424 /* make setting icon */
425 Evas_Object *icon_setting = _setting_icon_make();
426 retv_if(!icon_setting, VOLUME_ERROR_FAIL);
427 elm_object_part_content_set(ly_outer, "ic_setting", icon_setting);
428 view_info.icon_setting = icon_setting;
430 /* make volume icon */
431 Evas_Object *icon_volume = _volume_icon_make();
432 retv_if(!icon_volume, VOLUME_ERROR_FAIL);
433 elm_object_part_content_set(ly_outer, "ic_sound", icon_volume);
434 view_info.icon_volume = icon_volume;
437 Evas_Object *slider = _slider_make();
438 retv_if(!slider, VOLUME_ERROR_FAIL);
439 view_info.slider = slider;
440 elm_object_part_content_set(ly_outer, "sw.slider", slider);
442 /* add callback for hide */
443 elm_object_signal_callback_add(ly_outer, "hide,volume", "hide", _down_for_hide, NULL);
445 return VOLUME_ERROR_OK;
448 Evas_Object *add_volume_window(const char *name)
450 Evas_Object *eo = NULL;
454 eo = elm_win_add(NULL, name, ELM_WIN_NOTIFICATION);
456 evas = evas_object_evas_get(eo);
457 retv_if(!evas, NULL);
458 view_info.evas = evas;
460 elm_win_alpha_set(eo, EINA_TRUE);
461 elm_win_title_set(eo, name);
462 elm_win_borderless_set(eo, EINA_TRUE);
463 ecore_evas_name_class_set(ecore_evas_ecore_evas_get(evas), "SYSTEM_POPUP", "SYSTEM_POPUP");
464 elm_win_prop_focus_skip_set(eo, EINA_TRUE);
465 elm_win_role_set(eo, "no-dim");
467 elm_win_screen_size_get(eo, &x, &y, &w, &h);
468 _D("volume screen size => x: %d, y: %d, w: %d, h: %d", x, y, w, h);
473 static Eina_Bool _key_grab_cb(void *data)
477 Evas_Object *win = data;
479 _D("keygrab window is [%p]", win);
480 ret_up = elm_win_keygrab_set(win, KEY_VOLUMEUP, 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
481 _D("Result of volume up keygrab set : %d", ret_up);
482 ret_down = elm_win_keygrab_set(win, KEY_VOLUMEDOWN, 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
483 _D("Result of volume down keygrab set : %d", ret_down);
488 Evas_Object *volume_view_window_create(void)
490 Evas_Object *win = add_volume_window(PACKAGE);
492 _D("window is [%p]", win);
495 _D("view_info.win is [%p]", view_info.win);
497 evas_object_show(win);
499 ecore_timer_add(1.0f, _key_grab_cb, win);
503 elm_win_iconified_set(win, EINA_TRUE);
508 void _lock_sound_check(void)
510 int lcdoff_source = -1;
514 if (vconf_get_int(VCONFKEY_PM_LCDOFF_SOURCE, &lcdoff_source) < 0) {
515 _E("Failed to get vconfkey : VCONFKEY_PM_LCDOFF_SOURCE");
518 _D("lcd off source : %d", lcdoff_source);
520 if (lcdoff_source != VCONFKEY_PM_LCDOFF_BY_POWERKEY) {
521 _E("Should not play lock sound");
525 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, &lock_sound) < 0) {
526 _E("Failed to get vconfkey : VCONFKEY_SETAPPL_SOUND_LOCK_BOOL");
529 _D("lock sound : %d", lock_sound);
532 if (vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &lock_type) < 0) {
533 _E("Failed to get vconfkey : VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT");
536 _D("lock type : %d", lock_type);
538 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_LOCK);
542 Evas_Object* show_lockscreen_splash(const char* bg_path)
546 retv_if(bg_path == NULL, NULL);
548 if (view_info.lockscreen_splash) {
549 _E("There is remain fake_bg : remove old one");
550 evas_object_del(view_info.lockscreen_splash);
551 view_info.lockscreen_splash = NULL;
554 /* Check Lock Sound */
557 /* hide volume window */
558 if(VOLUME_ERROR_OK != volume_view_window_hide())
559 _E("Failed to hide window");
561 Evas_Object *win_splash = elm_win_add(NULL,"lockscreen_splash", ELM_WIN_NOTIFICATION);
564 _E("Failed to add splash window");
568 _D("Splash window created");
570 Evas_Object *bg = elm_bg_add(win_splash);
572 _D("Failed to get background");
573 evas_object_del(win_splash);
577 elm_win_resize_object_add(win_splash, bg);
578 elm_bg_file_set(bg, bg_path, NULL);
579 evas_object_show(bg);
581 evas_object_show(win_splash);
583 _D("Splash window shown");
585 view_info.lockscreen_splash = win_splash;
590 volume_error_e hide_lockscreen_splash(void)
594 if (!view_info.lockscreen_splash) {
595 _E("No splash window found");
596 return VOLUME_ERROR_FAIL;
599 evas_object_del(view_info.lockscreen_splash);
600 view_info.lockscreen_splash = NULL;
601 _D("Splash window closed");
603 return VOLUME_ERROR_OK;
605 static void _slider_start_cb(void *data, Evas_Object *obj, void *event_info)
607 view_info.is_slider_touching = EINA_TRUE;
609 volume_timer_del(TYPE_TIMER_POPUP);
611 volume_timer_add(0.2, TYPE_TIMER_SLIDER);
614 static void _slider_changed_cb(void *data, Evas_Object *obj, void *event_info)
616 volume_timer_del(TYPE_TIMER_POPUP);
620 sound_type_e sound_type = volume_control_get_sound_type_at_show();
621 _D("sound type at show : %d", sound_type);
623 val = elm_slider_value_get(view_info.slider);
625 _D("slider value : %d", val);
627 if (view_info.is_slider_touching)
630 volume_sound_change_set((int)val);
632 if (!volume_key_event_is_pressing_get()) {
633 volume_timer_add(3.0, TYPE_TIMER_POPUP);
637 if (!view_info.is_slider_touching) {
638 volume_timer_add(3.0, TYPE_TIMER_POPUP);
643 static void _slider_stop_cb(void *data, Evas_Object *obj, void *event_info)
645 view_info.is_slider_touching = EINA_FALSE;
647 volume_timer_del(TYPE_TIMER_SLIDER);
649 Evas_Object *slider = volume_view_slider_get();
650 ret_if(slider == NULL);
654 val = elm_slider_value_get(slider);
656 _D("slider value : %d", (int)val);
658 volume_sound_change_set((int)val);
660 volume_timer_add(3.0, TYPE_TIMER_POPUP);
663 static void _hide_launcher(void *data, Evas_Object *obj, const char *emission, const char *source)
665 evas_object_hide(view_info.win);
668 static void _button_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
670 volume_view_setting_icon_set(IMG_VOLUME_ICON_SETTINGS_PRESSED);
673 static void _app_control_error_check(int ret)
675 if (ret != APP_CONTROL_ERROR_NONE) {
678 case APP_CONTROL_ERROR_INVALID_PARAMETER :
679 _E("error : APP_CONTROL_ERROR_INVALID_PARAMETER");
681 case APP_CONTROL_ERROR_OUT_OF_MEMORY :
682 _E("error : APP_CONTROL_ERROR_OUT_OF_MEMORY");
684 case APP_CONTROL_ERROR_APP_NOT_FOUND :
685 _E("error : APP_CONTROL_ERROR_APP_NOT_FOUND");
687 case APP_CONTROL_ERROR_LAUNCH_REJECTED :
688 _E("error : APP_CONTROL_ERROR_LAUNCH_REJECTED");
691 _E("error : %d", ret);
697 static void _button_cb(void *data, Evas_Object *obj, void *event_info)
699 _D("volume setting is clicked");
703 if (evas_object_visible_get(view_info.win)) {
704 volume_timer_del(TYPE_TIMER_POPUP);
706 ret = app_control_create(&svc);
707 _app_control_error_check(ret);
709 ret = app_control_set_app_id(svc, "org.tizen.setting.volume");
710 _app_control_error_check(ret);
712 ret = app_control_send_launch_request(svc, NULL, NULL);
713 _app_control_error_check(ret);
715 if (VOLUME_ERROR_OK != volume_control_pause())
716 _E("Failed to pause volume");
718 app_control_destroy(svc);
722 static Evas_Object* _setting_icon_make()
724 _D("Setting ICON make");
725 Evas_Object *icon_setting = elm_icon_add(view_info.ly_outer);
726 retv_if(!icon_setting, NULL);
728 evas_object_size_hint_aspect_set(icon_setting, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
729 elm_image_resizable_set(icon_setting, EINA_TRUE, EINA_TRUE);
731 view_info.icon_setting = icon_setting;
733 volume_view_setting_icon_set(IMG_VOLUME_ICON_SETTINGS);
734 evas_object_show(icon_setting);
739 static Evas_Object* _volume_icon_make()
741 Evas_Object *icon_volume = elm_icon_add(view_info.ly_outer);
742 retv_if(!icon_volume, NULL);
744 evas_object_size_hint_aspect_set(icon_volume, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
745 elm_image_resizable_set(icon_volume, EINA_TRUE, EINA_TRUE);
746 evas_object_show(icon_volume);
751 static Evas_Object* _slider_make()
753 _D("Volume Slider Make");
754 sound_type_e sound_type = volume_control_get_sound_type_at_show();
755 _D("sound type at show : %d", sound_type);
757 int sound_step = volume_sound_sound_manager_step_get(sound_type);
758 _D("sound step : %d", sound_step);
760 int sound_val = volume_sound_level_get(sound_type);
761 if (sound_val == -1) {
762 _E("Failed to get volume level");
765 _D("sound value : %d", sound_val);
767 Evas_Object *slider = add_slider(view_info.ly_outer, 0, sound_step, sound_val);
768 retv_if(!slider, NULL);
769 evas_object_smart_callback_add(slider, "slider,drag,start", _slider_start_cb, NULL);
770 evas_object_smart_callback_add(slider, "changed", _slider_changed_cb, NULL);
771 evas_object_smart_callback_add(slider, "slider,drag,stop", _slider_stop_cb, NULL);