2 * Copyright (c) 2009-2014 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.
18 #include <vconf-keys.h>
19 #include <app_manager.h>
20 #include <efl_assist.h>
23 #include "_util_efl.h"
24 #include "_util_log.h"
30 #include "key_event.h"
32 #define VCONF_KEY_FMRADIO_RECORDING "memory/private/Sound/FMRadioRecording"
34 int myterm(bundle *b, void *data);
35 int mytimeout(bundle *b, void *data);
37 syspopup_handler handler = {
38 .def_term_fn = myterm,
39 .def_timeout_fn = mytimeout
42 static struct _s_info {
43 bundle *volume_bundle;
44 Ecore_Event_Handler *handler_qp_state;
45 Ecore_Timer *shape_timer;
47 Eina_Bool is_deleting;
48 Eina_Bool is_launching;
49 Eina_Bool is_quickpanel;
51 Eina_Bool is_warning_visible;
57 sound_type_e sound_type_at_show;
59 .volume_bundle = NULL,
60 .handler_qp_state = NULL,
63 .is_deleting = EINA_FALSE,
64 .is_launching = EINA_FALSE,
65 .is_quickpanel = EINA_FALSE,
67 .is_warning_visible = EINA_FALSE,
73 .sound_type_at_show = SOUND_TYPE_RINGTONE,
76 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info);
77 static Eina_Bool _shape_cb(void *data);
79 bundle* volume_control_reset_bundle_get(void)
81 return s_info.volume_bundle;
84 Eina_Bool volume_control_is_deleting_get(void)
86 return s_info.is_deleting;
89 Eina_Bool volume_control_is_launching_get(void)
91 return s_info.is_launching;
94 int volume_control_current_angle_get(void)
96 return s_info.current_angle;
99 sound_type_e volume_control_sound_type_at_show_get(void)
101 return s_info.sound_type_at_show;
104 int volume_control_viewport_height_get()
106 return s_info.viewport_height;
109 int volume_control_viewport_width_get()
111 return s_info.viewport_width;
114 Eina_Bool volume_control_viewport_is_warning_visible()
116 return s_info.is_warning_visible;
119 //int _cache_flush(void *data)
120 volume_error_e volume_control_cache_flush(void)
122 Evas_Object *win = volume_view_win_get();
123 retv_if(win == NULL, VOLUME_ERROR_FAIL);
127 int collection_cache = -1;
128 int image_cache = -1;
131 evas = evas_object_evas_get(win);
132 retv_if(!evas, VOLUME_ERROR_FAIL);
134 file_cache = edje_file_cache_get();
135 collection_cache = edje_collection_cache_get();
136 image_cache = evas_image_cache_get(evas);
137 font_cache = evas_font_cache_get(evas);
139 edje_file_cache_set(file_cache);
140 edje_collection_cache_set(collection_cache);
141 evas_image_cache_set(evas, 0);
142 evas_font_cache_set(evas, 0);
144 evas_image_cache_flush(evas);
145 evas_render_idle_flush(evas);
146 evas_font_cache_flush(evas);
148 edje_file_cache_flush();
149 edje_collection_cache_flush();
151 edje_file_cache_set(file_cache);
152 edje_collection_cache_set(collection_cache);
153 evas_image_cache_set(evas, image_cache);
154 evas_font_cache_set(evas, font_cache);
156 return VOLUME_ERROR_OK;
159 /* rotation event callback func. */
160 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info)
162 static int current_angle = -1;
163 int changed_angle = elm_win_rotation_get(obj);
165 Evas_Object *win = volume_view_win_get();
168 Evas_Object *ly_outer = volume_view_outer_layout_get();
171 _D("window rotated [%d] => [%d]", current_angle, changed_angle);
172 if(current_angle != changed_angle) {
173 current_angle = changed_angle;
174 s_info.current_angle = current_angle;
175 switch(current_angle){
177 _D("show,landscape");
178 elm_object_signal_emit(ly_outer, "show,landscape", "bg");
179 if(s_info.is_warning_visible)
181 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper");
185 _D("show,landscape");
186 elm_object_signal_emit(ly_outer, "show,landscape", "bg");
187 if(s_info.is_warning_visible)
189 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper");
194 elm_object_signal_emit(ly_outer, "show,portrait", "bg");
195 if(s_info.is_warning_visible)
197 elm_object_signal_emit(ly_outer, "show_warning", "clipper");
202 volume_x_input_event_shape(win, s_info.is_warning_visible);
206 static void _control_window_rotation_set(Evas_Object *win)
210 if (elm_win_wm_rotation_supported_get(win))
212 const int rots[4] = { 0, 90, 180, 270 };
213 elm_win_wm_rotation_available_rotations_set(win, (const int *)&rots, 4);
214 _D("set available rotations");
217 /* rotation event callback */
218 evas_object_smart_callback_add(win, "wm,rotation,changed", _rotate_changed_cb, NULL);
220 /* initialize degree */
221 _rotate_changed_cb(NULL, win, NULL);
224 static Eina_Bool _qp_state_check_cb(void *data, int type, void *event)
226 retv_if(!event, ECORE_CALLBACK_PASS_ON);
228 Ecore_X_Event_Client_Message *ev = event;
229 if (ev->message_type == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
231 if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_OFF)
233 _D("quickpanel off state");
234 s_info.is_quickpanel = EINA_FALSE;
236 else if (ev->data.l[0] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ON)
238 _D("quickpanel on state");
239 s_info.is_quickpanel = EINA_TRUE;
243 return ECORE_CALLBACK_PASS_ON;
246 static void _control_qp_state_handler_add(void)
248 Ecore_Event_Handler *handler_qp_state = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _qp_state_check_cb, NULL);
249 s_info.handler_qp_state = handler_qp_state;
253 volume_error_e volume_control_app_launch_with_bundle(const char *op_type, const char *operation, const char *pkgname)
255 app_control_h app_control;
258 ret = app_control_create(&app_control);
261 _E("Failed to create app control");
262 return VOLUME_ERROR_FAIL;
265 ret = app_control_set_app_id(app_control, pkgname);
268 _E("Failed to set appid");
269 app_control_destroy(app_control);
270 return VOLUME_ERROR_FAIL;
273 ret = app_control_add_extra_data(app_control, op_type, operation);
276 _E("Failed to add extra data");
277 app_control_destroy(app_control);
278 return VOLUME_ERROR_FAIL;
281 ret = app_control_send_launch_request(app_control, NULL, NULL);
282 _D("launch app with service : [%s][%d]", pkgname, ret);
284 app_control_destroy(app_control);
286 return VOLUME_ERROR_OK;
289 //int _get_vconf_idlelock
290 int volume_control_vconf_idlelock_get(void)
292 int lock = IDLELOCK_OFF;
293 int pm_state = VCONFKEY_PM_STATE_NORMAL;
295 /* Check Idle-Lock */
296 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) < 0)
298 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
299 return IDLELOCK_ERROR;
301 _D("idlelock vconf : %d", lock);
304 if(vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
306 _E("Failed to get vconfkey : VCONFKEY_PM_STATE");
307 return IDLELOCK_ERROR;
309 _D("PM STATE vconf : %d", pm_state);
311 return (lock == VCONFKEY_IDLE_LOCK ||
312 pm_state == VCONFKEY_PM_STATE_LCDOFF ||
313 pm_state == VCONFKEY_PM_STATE_SLEEP
314 ) ? IDLELOCK_ON : IDLELOCK_OFF;
318 int volume_control_status_check(int *lock, sound_type_e *sound_type)
320 *lock = volume_control_vconf_idlelock_get();
321 *sound_type = volume_sound_sound_manager_type_get();
322 _D("lock : %d / sound_type : %d", *lock, *sound_type);
324 if(*lock == IDLELOCK_ON)
326 if(*sound_type == SOUND_TYPE_RINGTONE)
328 _D("IDLELOCK is ON / sound type is Ringtone");
329 return LOCK_AND_NOT_MEDIA;
332 if(*sound_type != SOUND_TYPE_RINGTONE)
334 _D("IDLELOCK is ON / sound type is not Ringtone(media or alaram)");
335 return LOCK_AND_MEDIA;
339 _D("IDLELOCK is OFF / normal case");
341 return UNLOCK_STATUS;
344 static Eina_Bool _idler_top_position_grab(void *data)
346 volume_key_event_key_grab(-1, TOP_POSITION_GRAB);
348 return ECORE_CALLBACK_CANCEL;
351 void volume_control_event_shape(Eina_Bool is_warning_visible)
353 Evas_Object *win = volume_view_win_get();
354 volume_x_input_event_shape(win, is_warning_visible);
357 void volume_control_show_hide_worning()
359 Evas_Object *ly_outer = volume_view_outer_layout_get();
360 sound_type_e sound_type = volume_sound_sound_manager_type_get();
361 int volume = volume_sound_sound_manager_volume_get(sound_type);
363 if(sound_type == SOUND_TYPE_MEDIA
364 && volume>VOLUME_MAX_SAFETY_VOLUME_LEVEL)
366 if(!s_info.is_warning_visible)
368 s_info.is_warning_visible = EINA_TRUE;
370 if(s_info.current_angle == 90 || s_info.current_angle == 270)
372 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper"); //landscape
376 elm_object_signal_emit(ly_outer, "show_warning", "clipper"); //landscape
379 volume_control_event_shape(EINA_TRUE);
382 else if(s_info.is_warning_visible)
384 s_info.is_warning_visible = EINA_FALSE;
386 if(s_info.current_angle == 90 || s_info.current_angle == 270)
388 elm_object_signal_emit(ly_outer, "hide_warning_l", "clipper"); //landscape
392 elm_object_signal_emit(ly_outer, "hide_warning", "clipper"); //landscape
395 volume_control_event_shape(EINA_FALSE);
399 Eina_Bool volume_control_show(void)
402 int lock = IDLELOCK_ON;
403 int lock_state = VCONFKEY_IDLE_UNLOCK;
405 bool is_running = false;
408 static Eina_Bool once = EINA_TRUE;
409 Evas_Object *win = NULL;
410 sound_type_e sound_type = 0;
412 retv_if(s_info.is_deleting, EINA_FALSE);
414 s_info.is_new = EINA_TRUE;
416 win = volume_view_win_get();
417 retv_if(!win, EINA_FALSE);
419 status = volume_control_status_check(&lock, &sound_type);
420 _D("status : %d", status);
422 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state) < 0)
424 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
428 if(status == LOCK_AND_NOT_MEDIA || lock_state == VCONFKEY_IDLE_LAUNCHING_LOCK)
430 _D("Lock and Not Media");
431 if(evas_object_visible_get(win))
433 if(VOLUME_ERROR_OK != volume_control_close())
435 _E("Failed to close volume");
438 if(VOLUME_ERROR_OK != volume_control_cache_flush())
440 _E("Failed to flush cache");
445 else if(status != LOCK_AND_NOT_MEDIA)
447 if(status == UNLOCK_STATUS)
449 /* Show volume window */
450 if(VOLUME_ERROR_OK != volume_view_window_show())
452 _E("Failed to show volume window");
455 /* register outer window event */
456 if(VOLUME_ERROR_OK != volume_x_input_event_register())
458 _E("Failed to add x input event handler");
461 if(syspopup_has_popup(s_info.volume_bundle))
463 syspopup_reset(s_info.volume_bundle);
468 ecore_idler_add(_idler_top_position_grab, NULL);
473 s_info.is_launching = EINA_TRUE;
475 int volume = volume_sound_sound_manager_volume_get(sound_type);
476 _D("volume : %d", volume);
478 int sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
479 _D("sound status : %d", sound);
481 int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
482 _D("vibration : %d", vibration);
484 if(((vibration == 1 && sound == 0) || sound == 0) && sound_type == SOUND_TYPE_RINGTONE)
489 if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
491 _E("Failed to set volume value to slider");
494 /* Set Volume icon */
495 //@TODO: need to check
496 volume_view_volume_icon_set(sound_type, sound, vibration);
498 if(!s_info.shape_timer)
500 s_info.shape_timer = ecore_timer_add(0.1, _shape_cb, NULL);
504 ecore_timer_del(s_info.shape_timer);
505 s_info.shape_timer = NULL;
507 s_info.shape_timer = ecore_timer_add(0.1, _shape_cb, NULL);
517 volume_error_e volume_control_close(void)
519 retv_if(volume_control_is_deleting_get(), VOLUME_ERROR_FAIL);
521 _D("Start closing volume");
524 int count_grabed = volume_key_event_count_grabed_get();
526 Ecore_X_Window input_win = volume_key_event_input_window_get();
527 retv_if(!input_win, VOLUME_ERROR_FAIL);
529 s_info.is_deleting = EINA_TRUE;
531 /* unregister outer event handler */
532 if(VOLUME_ERROR_OK != volume_x_input_event_unregister())
534 _E("Failed to unregister x input event handler");
535 // s_info.is_deleting = EINA_FALSE;
536 // return VOLUME_ERROR_FAIL;
539 for(i = 0; i < count_grabed; i++)
541 if(VOLUME_ERROR_OK != volume_key_event_key_ungrab())
543 _E("Failed to ungrab key");
546 _D("ungrab key : %d/%d", i+1, count_grabed);
548 volume_key_event_count_grabed_set(0);
549 if(VOLUME_ERROR_OK != volume_key_event_key_grab(input_win, SHARED_GRAB))
551 _E("Failed to grab key : SHARED_GRAB");
554 volume_timer_del(TYPE_TIMER_SU);
555 volume_timer_del(TYPE_TIMER_SD);
556 volume_timer_del(TYPE_TIMER_SLIDER);
557 volume_timer_del(TYPE_TIMER_POPUP);
560 if(VOLUME_ERROR_OK != volume_view_window_hide())
562 _E("Failed to hide window");
565 s_info.is_deleting = EINA_FALSE;
566 s_info.is_launching = EINA_FALSE;
568 _D("End closing volume");
573 static void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data)
575 int ret = EINA_FALSE;
577 if(vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &ret) < 0)
579 _E("Failed to get vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
586 _D("any other App grab volume hard key");
587 if(VOLUME_ERROR_OK != volume_control_close()) {
588 _E("Failed to close volume");
591 if(VOLUME_ERROR_OK != volume_control_cache_flush()) {
592 _E("Failed to flush cache");
595 if(vconf_set_int(VCONFKEY_STARTER_USE_VOLUME_KEY, 0) < 0) {
596 _E("Failed to get vconfkey : VCONFKEY_STATER_USE_VOLUME_KEY");
602 _D("setting App grab volume hard key");
603 // _close_volume(ad);
608 static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data)
610 int lock = VCONFKEY_IDLE_UNLOCK;
612 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) < 0)
614 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
617 _D("idle lock state : %d", lock);
619 if(lock == VCONFKEY_IDLE_LAUNCHING_LOCK)
621 const char *splash_path = vconf_get_str(VCONFKEY_IDLE_LOCK_BGSET);
625 // show_lockscreen_splash(splash_path);
627 _E("No background found");
630 if(VOLUME_ERROR_OK != volume_view_window_hide())
632 _E("Failed to hide window");
635 else if(lock == VCONFKEY_IDLE_UNLOCK)
637 // hide_lockscreen_splash();
641 static void _notify_pm_lcdoff_cb(keynode_t * node, void *data)
643 if(VOLUME_ERROR_OK != volume_control_close())
645 _E("Failed to close volume");
648 if(VOLUME_ERROR_OK != volume_control_cache_flush())
650 _E("Failed to flush cache");
654 void volume_control_vconfkey_register(void)
656 /* other app grab volume key => close volume */
657 if(vconf_notify_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb, NULL) != 0)
659 _E("Failed to register callback function : VCONFKEY_STARTER_USE_VOLUME_KEY");
662 /* Lock screen status vconf changed callback */
663 if(vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb, NULL) != 0)
665 _E("Failed to notify vconfkey : VCONFKEY_IDLE_LOCK_STATE");
668 if (vconf_notify_key_changed(VCONFKEY_PM_LCDOFF_SOURCE, _notify_pm_lcdoff_cb, NULL) != 0) {
669 _E("Failed to notify vconfkey : VCONFKEY_PM_LCDOFF_SOURCE");
673 void volume_control_vconfkey_unregister(void)
675 /* other app grab volume key => close volume */
676 if(vconf_ignore_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb) < 0)
678 _E("Failed to ignore vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
681 /* Lock screen status vconf changed callback */
682 if(vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb) < 0)
684 _E("Failed to ignore vconfkey : VCONFKEY_IDLE_LOCK_STATE");
687 if (vconf_ignore_key_changed
688 (VCONFKEY_PM_LCDOFF_SOURCE, _notify_pm_lcdoff_cb) != 0) {
689 _E("Fail vconf_ignore_key_changed : VCONFKEY_PM_LCDOFF_SOURCE");
693 //int _app_pause(struct appdata *ad)
694 volume_error_e volume_control_pause(void)
696 Evas_Object *win = volume_view_win_get();
697 retv_if(!win, VOLUME_ERROR_FAIL);
699 if(evas_object_visible_get(win)) {
700 if(VOLUME_ERROR_OK != volume_control_close())
702 _E("Failed to close volume");
705 if(VOLUME_ERROR_OK != volume_control_cache_flush())
707 _E("Failed to flush cache");
711 return VOLUME_ERROR_OK;
714 int myterm(bundle *b, void *data)
716 if(VOLUME_ERROR_OK != volume_control_close())
718 _E("Failed to close volume");
720 if(VOLUME_ERROR_OK != volume_control_cache_flush())
722 _E("Failed to flush cache");
728 int mytimeout(bundle *b, void *data)
733 volume_error_e volume_control_reset(bundle *b)
735 _D("Volume control reset");
736 Evas_Object *win = volume_view_win_get();
737 retv_if(!win, VOLUME_ERROR_FAIL);
740 int lock = IDLELOCK_ON;
742 static int once = EINA_TRUE;
745 ret = syspopup_create(b, &handler, win, NULL);
746 retvm_if(ret < 0, VOLUME_ERROR_FAIL, "Failed to create syspopup");
747 s_info.volume_bundle = bundle_dup(b);
751 sound_type_e sound_type = volume_sound_sound_manager_type_get();
752 _D("sound type : %d", sound_type);
754 int volume = volume_sound_sound_manager_volume_get(sound_type);
755 _D("volume : %d", volume);
757 const char *show_volume = bundle_get_val(b, SHOWVOLUME);
758 retv_if(!show_volume, VOLUME_ERROR_FAIL);
760 if(!strncasecmp(show_volume, ISTRUE, strlen(ISTRUE)))
762 _D("Bundle : %s", show_volume);
763 if(lock == IDLELOCK_OFF)
766 volume_timer_add(3.0, TYPE_TIMER_POPUP);
767 volume_control_show();
771 return VOLUME_ERROR_OK;
774 volume_error_e volume_control_initialize(void)
776 _D("Volume control initialize");
779 elm_config_preferred_engine_set("opengl_x11");
782 /* Create main window */
783 Evas_Object *win = volume_view_window_create();
784 retv_if(!win, VOLUME_ERROR_FAIL);
786 /* Create input_window */
787 if(VOLUME_ERROR_OK != volume_key_event_input_window_create()) {
788 _E("Failed to create input window");
789 return VOLUME_ERROR_FAIL;
792 /* Create volume layout */
793 if(VOLUME_ERROR_OK != volume_view_layout_create(win)) {
794 _E("Failed to create volume layout");
795 return VOLUME_ERROR_FAIL;
798 ecore_x_window_size_get(ecore_x_window_root_first_get(), &(s_info.viewport_width), &(s_info.viewport_height));
801 /* Set available rotations */
802 _control_window_rotation_set(win);
804 /* Register vconfkey changed callback
805 * : VCONFKEY_STARTER_USE_VOLUME_KEY
806 * : VCONFKEY_IDLE_LOCK_STATE
807 * : VCONFKEY_LOCKSCREEN_SVIEW_STATE
809 volume_control_vconfkey_register();
811 /* Register vconfkey changed callback
812 * : VCONFKEY_SETAPPL_SOUND_STATUS_BOOL
813 * : VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL
815 volume_sound_vconfkey_register();
817 /* Add key event handler */
818 volume_key_event_handler_add();
820 /* Add quick panel event handler */
821 _control_qp_state_handler_add();
823 /* Register volume changed callback */
824 volume_sound_mm_sound_init();
827 ea_theme_changeable_ui_enabled_set(EINA_TRUE);
829 return VOLUME_ERROR_OK;
832 void volume_control_deinitialize(void)
834 /* Unregister vconfkey changed callback */
835 volume_control_vconfkey_unregister();
837 /* Unregister sound vconfkey changed callback */
838 volume_sound_vconfkey_unregister();
841 static Eina_Bool _shape_cb(void *data)
844 volume_control_event_shape(s_info.is_warning_visible);
845 s_info.shape_timer = NULL;
846 return ECORE_CALLBACK_CANCEL;