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 <bluetooth.h>
21 #include <bluetooth_internal.h>
23 //#include <bluetooth_extention.h>
26 #include "_util_efl.h"
27 #include "_util_log.h"
33 #include "key_event.h"
36 #define VCONF_KEY_FMRADIO_RECORDING "memory/private/Sound/FMRadioRecording"
38 struct _control_s_info{
39 bundle *volume_bundle;
40 Ecore_Event_Handler *handler_qp_state;
41 Ecore_Timer *shape_timer;
43 Eina_Bool is_deleting;
44 Eina_Bool is_launching;
46 Eina_Bool is_warning_visible;
54 sound_type_e sound_type_at_show;
56 static struct _control_s_info control_info = {
57 .volume_bundle = NULL,
58 .handler_qp_state = NULL,
61 .is_deleting = EINA_FALSE,
62 .is_launching = EINA_FALSE,
64 .is_warning_visible = EINA_FALSE,
65 .reset_once = EINA_FALSE,
66 .show_once = EINA_FALSE,
72 .sound_type_at_show = SOUND_TYPE_RINGTONE,
75 static int _myterm(bundle *b, void *data);
76 static int _mytimeout(bundle *b, void *data);
77 static void _notify_pm_lcdoff_cb(keynode_t * node, void *data);
78 static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data);
79 static void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data);
80 static Eina_Bool _shape_cb(void *data);
81 static Eina_Bool _idler_top_position_grab(void *data);
82 static void _control_set_window_rotation(Evas_Object *win);
83 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info);
85 bundle* volume_control_reset_get_bundle(void)
87 return control_info.volume_bundle;
90 Eina_Bool volume_control_get_is_deleting(void)
92 return control_info.is_deleting;
95 Eina_Bool volume_control_get_is_launching(void)
97 return control_info.is_launching;
100 int volume_control_get_current_angle(void)
102 return control_info.current_angle;
105 sound_type_e volume_control_get_sound_type_at_show(void)
107 return control_info.sound_type_at_show;
110 int volume_control_get_viewport_height()
112 return control_info.viewport_height;
115 int volume_control_get_viewport_width()
117 return control_info.viewport_width;
120 Eina_Bool volume_control_viewport_is_warning_visible()
122 return control_info.is_warning_visible;
125 volume_error_e volume_control_cache_flush(void)
127 Evas_Object *win = volume_view_win_get();
128 retv_if(win == NULL, VOLUME_ERROR_FAIL);
132 int collection_cache = -1;
133 int image_cache = -1;
136 evas = evas_object_evas_get(win);
137 retv_if(!evas, VOLUME_ERROR_FAIL);
139 file_cache = edje_file_cache_get();
140 collection_cache = edje_collection_cache_get();
141 image_cache = evas_image_cache_get(evas);
142 font_cache = evas_font_cache_get(evas);
144 edje_file_cache_set(file_cache);
145 edje_collection_cache_set(collection_cache);
146 evas_image_cache_set(evas, 0);
147 evas_font_cache_set(evas, 0);
149 evas_image_cache_flush(evas);
150 evas_render_idle_flush(evas);
151 evas_font_cache_flush(evas);
153 edje_file_cache_flush();
154 edje_collection_cache_flush();
156 edje_file_cache_set(file_cache);
157 edje_collection_cache_set(collection_cache);
158 evas_image_cache_set(evas, image_cache);
159 evas_font_cache_set(evas, font_cache);
161 return VOLUME_ERROR_OK;
164 /* rotation event callback func. */
165 volume_error_e volume_control_app_launch_with_bundle(const char *op_type, const char *operation, const char *pkgname)
167 app_control_h app_control;
170 ret = app_control_create(&app_control);
172 _E("Failed to create app control");
173 return VOLUME_ERROR_FAIL;
176 ret = app_control_set_app_id(app_control, pkgname);
179 _E("Failed to set appid");
180 app_control_destroy(app_control);
181 return VOLUME_ERROR_FAIL;
184 ret = app_control_add_extra_data(app_control, op_type, operation);
187 _E("Failed to add extra data");
188 app_control_destroy(app_control);
189 return VOLUME_ERROR_FAIL;
192 ret = app_control_send_launch_request(app_control, NULL, NULL);
193 _D("launch app with service : [%s][%d]", pkgname, ret);
195 app_control_destroy(app_control);
197 return VOLUME_ERROR_OK;
200 int volume_control_get_vconf_idlelock(void)
202 int lock = IDLELOCK_OFF;
203 int pm_state = VCONFKEY_PM_STATE_NORMAL;
205 /* Check Idle-Lock */
206 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) < 0)
208 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
209 return IDLELOCK_ERROR;
211 _D("idlelock vconf : %d", lock);
214 if(vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
216 _E("Failed to get vconfkey : VCONFKEY_PM_STATE");
217 return IDLELOCK_ERROR;
219 _D("PM STATE vconf : %d", pm_state);
221 return (lock == VCONFKEY_IDLE_LOCK ||
222 pm_state == VCONFKEY_PM_STATE_LCDOFF ||
223 pm_state == VCONFKEY_PM_STATE_SLEEP
224 ) ? IDLELOCK_ON : IDLELOCK_OFF;
228 int volume_control_check_status(int *lock, sound_type_e *sound_type)
230 *lock = volume_control_get_vconf_idlelock();
231 *sound_type = volume_sound_sound_manager_type_get();
232 _D("lock : %d / sound_type : %d", *lock, *sound_type);
234 if(*lock == IDLELOCK_ON)
236 if(*sound_type == SOUND_TYPE_RINGTONE)
238 _D("IDLELOCK is ON / sound type is Ringtone");
239 return LOCK_AND_NOT_MEDIA;
242 if(*sound_type != SOUND_TYPE_RINGTONE)
244 _D("IDLELOCK is ON / sound type is not Ringtone(media or alaram)");
245 return LOCK_AND_MEDIA;
249 _D("IDLELOCK is OFF / normal case");
251 return UNLOCK_STATUS;
254 void volume_control_shape_event_area(Eina_Bool is_warning_visible)
256 _D("shape event area");
257 Evas_Object *win = volume_view_win_get();
258 //volume_x_input_event_shape(win, is_warning_visible);
261 void volume_control_show_hide_worning()
263 Evas_Object *ly_outer = volume_view_outer_layout_get();
264 sound_type_e sound_type = volume_sound_sound_manager_type_get();
265 int volume = volume_sound_sound_manager_volume_get(sound_type);
267 if(sound_type == SOUND_TYPE_MEDIA
268 && volume>VOLUME_MAX_SAFETY_VOLUME_LEVEL)
270 if(!control_info.is_warning_visible)
272 control_info.is_warning_visible = EINA_TRUE;
274 if(control_info.current_angle == 90 || control_info.current_angle == 270)
276 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper"); //landscape
280 elm_object_signal_emit(ly_outer, "show_warning", "clipper"); //landscape
283 volume_control_shape_event_area(EINA_TRUE);
286 else if(control_info.is_warning_visible)
288 control_info.is_warning_visible = EINA_FALSE;
290 if(control_info.current_angle == 90 || control_info.current_angle == 270)
292 elm_object_signal_emit(ly_outer, "hide_warning_l", "clipper"); //landscape
296 elm_object_signal_emit(ly_outer, "hide_warning", "clipper"); //landscape
299 volume_control_shape_event_area(EINA_FALSE);
303 int volume_register_shape_timer()
305 if (control_info.shape_timer) {
306 ecore_timer_del(control_info.shape_timer);
307 control_info.shape_timer = NULL;
310 control_info.shape_timer = ecore_timer_add(0.1, _shape_cb, NULL);
312 if (control_info.shape_timer)
313 return VOLUME_ERROR_OK;
315 return VOLUME_ERROR_FAIL;
318 void volume_control_check_syspopup()
320 if(syspopup_has_popup(control_info.volume_bundle)) {
321 syspopup_reset(control_info.volume_bundle);
325 void volume_control_check_once(void)
327 if(control_info.show_once) {
328 ecore_idler_add(_idler_top_position_grab, NULL);
329 control_info.show_once = EINA_FALSE;
333 Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int sound, bool bt_opened)
335 _D("Volume control show");
336 Evas_Object *win = NULL;
340 retv_if(control_info.is_deleting, EINA_FALSE);
342 control_info.is_new = EINA_TRUE;
344 win = volume_view_win_get();
345 retv_if(!win, EINA_FALSE);
347 if(status == LOCK_AND_NOT_MEDIA)
349 _D("Lock and Not Media");
350 if(evas_object_visible_get(win))
352 if(VOLUME_ERROR_OK != volume_control_hide_view())
354 _E("Failed to close volume");
357 if(VOLUME_ERROR_OK != volume_control_cache_flush())
359 _E("Failed to flush cache");
364 _D("UNLOCK or LOCK_AND_MEDIA");
365 control_info.sound_type_at_show = sound_type;
367 if(status == UNLOCK_STATUS) {
368 if(VOLUME_ERROR_OK != volume_view_window_show()) {
369 _E("Failed to show volume window");
372 /*if(VOLUME_ERROR_OK != volume_x_input_event_register()) {
373 _E("Failed to add x input event handler");
376 volume_control_check_syspopup();
378 volume_control_check_once();
381 control_info.is_launching = EINA_TRUE;
383 if(bt_opened == 1 && sound_type == SOUND_TYPE_CALL)
385 _D("bt is opened and is calling");
386 volume = bt_get_bt_volume();
387 _D("bt volume is : %d", volume);
389 if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
391 _E("Failed to set volume value to slider");
396 volume = volume_sound_sound_manager_volume_get(sound_type);
397 _D("volume : %d", volume);
399 vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
400 _D("vibration : %d", vibration);
402 if(((vibration == 1 && sound == 0) || sound == 0) && sound_type == SOUND_TYPE_RINGTONE)
407 if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
409 _E("Failed to set volume value to slider");
413 //@TODO: need to check
414 volume_view_volume_icon_set(sound_type, sound, vibration, bt_opened);
416 if(VOLUME_ERROR_OK != volume_register_shape_timer())
418 _E("Failed to register shape_timer");
425 volume_error_e volume_control_close_bt_display(void)
427 retv_if(volume_control_get_is_deleting(), VOLUME_ERROR_FAIL);
429 _D("Start closing bt display");
431 Ecore_X_Window input_win = volume_key_event_input_window_get();
432 retv_if(!input_win, VOLUME_ERROR_FAIL);
434 control_info.is_deleting = EINA_TRUE;
436 /* unregister outer event handler */
437 /*if(VOLUME_ERROR_OK != volume_x_input_event_unregister())
439 _E("Failed to unregister x input event handler");
443 if(VOLUME_ERROR_OK != volume_view_window_hide())
445 _E("Failed to hide window");
448 control_info.is_deleting = EINA_FALSE;
450 _D("End closing bt display");
451 volume_timer_del(TYPE_TIMER_BT);
456 volume_error_e volume_control_hide_view(void)
458 retv_if(volume_control_get_is_deleting(), VOLUME_ERROR_FAIL);
460 _D("Start closing volume view");
465 int count_grabed = volume_key_event_count_grabed_get();
467 control_info.is_deleting = EINA_TRUE;
469 elm_win_keygrab_unset(volume_view_win_get(), KEY_VOLUMEUP, 0, 0);
470 elm_win_keygrab_unset(volume_view_win_get(), KEY_VOLUMEDOWN, 0, 0);
471 volume_key_event_count_grabed_set(0);
472 ret = elm_win_keygrab_set(volume_view_win_get(), KEY_VOLUMEUP, 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
473 ret1 = elm_win_keygrab_set(volume_view_win_get(), KEY_VOLUMEDOWN, 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
475 volume_timer_del(TYPE_TIMER_SU);
476 volume_timer_del(TYPE_TIMER_SD);
477 volume_timer_del(TYPE_TIMER_SLIDER);
478 volume_timer_del(TYPE_TIMER_POPUP);
481 if (VOLUME_ERROR_OK != volume_view_window_hide()) {
482 _E("Failed to hide window");
485 control_info.is_deleting = EINA_FALSE;
486 control_info.is_launching = EINA_FALSE;
488 _D("End closing volume view");
493 void volume_control_register_vconfkey(void)
495 /* other app grab volume key => close volume */
496 if(vconf_notify_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb, NULL) != 0)
498 _E("Failed to register callback function : VCONFKEY_STARTER_USE_VOLUME_KEY");
501 /* Lock screen status vconf changed callback */
502 if(vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb, NULL) != 0)
504 _E("Failed to notify vconfkey : VCONFKEY_IDLE_LOCK_STATE");
507 if (vconf_notify_key_changed(VCONFKEY_PM_LCDOFF_SOURCE, _notify_pm_lcdoff_cb, NULL) != 0) {
508 _E("Failed to notify vconfkey : VCONFKEY_PM_LCDOFF_SOURCE");
512 void volume_control_unregister_vconfkey(void)
514 /* other app grab volume key => close volume */
515 if(vconf_ignore_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb) < 0)
517 _E("Failed to ignore vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
520 /* Lock screen status vconf changed callback */
521 if(vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb) < 0)
523 _E("Failed to ignore vconfkey : VCONFKEY_IDLE_LOCK_STATE");
526 if (vconf_ignore_key_changed
527 (VCONFKEY_PM_LCDOFF_SOURCE, _notify_pm_lcdoff_cb) != 0) {
528 _E("Fail vconf_ignore_key_changed : VCONFKEY_PM_LCDOFF_SOURCE");
532 volume_error_e volume_control_pause(void)
534 Evas_Object *win = volume_view_win_get();
535 retv_if(!win, VOLUME_ERROR_FAIL);
537 if(evas_object_visible_get(win)) {
538 if(VOLUME_ERROR_OK != volume_control_hide_view())
540 _E("Failed to close volume");
543 if(VOLUME_ERROR_OK != volume_control_cache_flush())
545 _E("Failed to flush cache");
549 return VOLUME_ERROR_OK;
552 volume_error_e volume_control_reset(bundle *b)
554 _D("Volume control reset");
555 Evas_Object *win = volume_view_win_get();
556 retv_if(!win, VOLUME_ERROR_FAIL);
559 int lock = IDLELOCK_ON;
564 bool bt_opened = false;
565 sound_type_e sound_type = 0;
566 const char *show_volume = NULL;
568 if(control_info.reset_once) {
569 static syspopup_handler handler = {
570 .def_term_fn = _myterm,
571 .def_timeout_fn = _mytimeout
574 ret = syspopup_create(b, &handler, win, NULL);
575 retvm_if(ret < 0, VOLUME_ERROR_FAIL, "Failed to create syspopup");
576 control_info.volume_bundle = bundle_dup(b);
577 control_info.reset_once = EINA_FALSE;
580 status = volume_control_check_status(&lock, &sound_type);
581 _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
583 volume = volume_sound_sound_manager_volume_get(sound_type);
584 _D("volume : %d", volume);
586 sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
587 _D("sound status : %d", sound);
589 error = bt_ag_is_sco_opened(&bt_opened);
590 if(error != BT_ERROR_NONE)
592 _E("bt_ag_is_sco_opened return [%d]", error);
594 _D("BT state %d", bt_opened);
596 show_volume = bundle_get_val(b, SHOWVOLUME);
597 retv_if(!show_volume, VOLUME_ERROR_FAIL);
599 if(!strncasecmp(show_volume, ISTRUE, strlen(ISTRUE)))
601 _D("Bundle : %s", show_volume);
602 if(lock == IDLELOCK_OFF)
605 volume_timer_add(3.0, TYPE_TIMER_POPUP);
606 volume_control_show_view(status, sound_type, sound, bt_opened);
610 return VOLUME_ERROR_OK;
613 volume_error_e volume_control_initialize(void)
615 _D("Volume control initialize");
617 /* Create main window */
618 Evas_Object *win = volume_view_window_create();
619 retv_if(!win, VOLUME_ERROR_FAIL);
621 /* Create volume layout */
622 if(VOLUME_ERROR_OK != volume_view_layout_create(win)) {
623 _E("Failed to create volume layout");
624 return VOLUME_ERROR_FAIL;
627 elm_win_screen_size_get(win, NULL, NULL, &(control_info.viewport_width), &(control_info.viewport_height));
630 /* Set available rotations */
631 _control_set_window_rotation(win);
633 /* Register vconfkey changed callback
634 * : VCONFKEY_STARTER_USE_VOLUME_KEY
635 * : VCONFKEY_IDLE_LOCK_STATE
636 * : VCONFKEY_LOCKSCREEN_SVIEW_STATE
638 volume_control_register_vconfkey();
640 /* Register vconfkey changed callback
641 * : VCONFKEY_SETAPPL_SOUND_STATUS_BOOL
642 * : VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL
644 volume_sound_vconfkey_register();
646 /* Add key event handler */
647 volume_key_event_handler_add();
649 /* Register volume changed callback */
650 volume_sound_mm_sound_init();
652 /* BT initialize and register changed callback */
655 return VOLUME_ERROR_OK;
658 void volume_control_deinitialize(void)
660 /* Unregister vconfkey changed callback */
661 volume_control_unregister_vconfkey();
663 /* Unregister sound vconfkey changed callback */
664 volume_sound_vconfkey_unregister();
666 /* Unregister bt changed callback */
670 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info)
672 static int current_angle = -1;
673 int changed_angle = elm_win_rotation_get(obj);
676 Evas_Object *ly_outer = volume_view_outer_layout_get();
679 _D("window rotated [%d] => [%d]", current_angle, changed_angle);
680 if(current_angle != changed_angle) {
681 current_angle = changed_angle;
682 control_info.current_angle = current_angle;
683 switch(current_angle){
686 _D("show,landscape");
687 elm_object_signal_emit(ly_outer, "show,landscape", "bg");
688 if(control_info.is_warning_visible)
690 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper");
695 elm_object_signal_emit(ly_outer, "show,portrait", "bg");
696 if(control_info.is_warning_visible)
698 elm_object_signal_emit(ly_outer, "show_warning", "clipper");
703 //volume_x_input_eddddent_shape(obj, control_info.is_warning_visible);
707 static void _control_set_window_rotation(Evas_Object *win)
711 if (elm_win_wm_rotation_supported_get(win)) {
712 const int rots[4] = { 0, 90, 180, 270 };
713 elm_win_wm_rotation_available_rotations_set(win, (const int *)&rots, 4);
714 _D("set available rotations");
717 /* rotation event callback */
718 evas_object_smart_callback_add(win, "wm,rotation,changed", _rotate_changed_cb, NULL);
720 /* initialize degree */
721 _rotate_changed_cb(NULL, win, NULL);
724 static Eina_Bool _idler_top_position_grab(void *data)
726 Evas_Object *win = NULL;
727 _D("Unset shared keygrab");
729 win = volume_view_win_get();
730 elm_win_keygrab_unset(win, KEY_VOLUMEUP, 0, 0);
731 elm_win_keygrab_unset(win, KEY_VOLUMEDOWN, 0, 0);
732 elm_win_keygrab_set(win, KEY_VOLUMEUP, 0, 0, 0, ELM_WIN_KEYGRAB_TOPMOST);
733 elm_win_keygrab_set(win, KEY_VOLUMEDOWN, 0, 0, 0, ELM_WIN_KEYGRAB_TOPMOST);
735 return ECORE_CALLBACK_CANCEL;
738 static Eina_Bool _shape_cb(void *data)
740 LOGD("shape callback");
741 volume_control_shape_event_area(control_info.is_warning_visible);
742 control_info.shape_timer = NULL;
743 return ECORE_CALLBACK_CANCEL;
746 static void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data)
748 int ret = EINA_FALSE;
750 if(vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &ret) < 0)
752 _E("Failed to get vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
759 _D("any other App grab volume hard key");
760 if(VOLUME_ERROR_OK != volume_control_hide_view()) {
761 _E("Failed to close volume");
764 if(VOLUME_ERROR_OK != volume_control_cache_flush()) {
765 _E("Failed to flush cache");
768 if(vconf_set_int(VCONFKEY_STARTER_USE_VOLUME_KEY, 0) < 0) {
769 _E("Failed to get vconfkey : VCONFKEY_STATER_USE_VOLUME_KEY");
775 _D("setting App grab volume hard key");
779 static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data)
781 int lock = VCONFKEY_IDLE_UNLOCK;
783 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) < 0)
785 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
788 _D("idle lock state : %d", lock);
790 if(lock == VCONFKEY_IDLE_LAUNCHING_LOCK)
792 if(VOLUME_ERROR_OK != volume_view_window_hide())
794 _E("Failed to hide window");
799 static void _notify_pm_lcdoff_cb(keynode_t * node, void *data)
801 if(VOLUME_ERROR_OK != volume_control_hide_view())
803 _E("Failed to close volume");
806 if(VOLUME_ERROR_OK != volume_control_cache_flush())
808 _E("Failed to flush cache");
812 static int _mytimeout(bundle *b, void *data)
817 static int _myterm(bundle *b, void *data)
819 if (VOLUME_ERROR_OK != volume_control_hide_view())
821 _E("Failed to close volume");
823 if (VOLUME_ERROR_OK != volume_control_cache_flush())
825 _E("Failed to flush cache");