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>
22 #include <bluetooth_extension.h>
23 #include <bundle_internal.h>
26 #include "_util_efl.h"
27 #include "_util_log.h"
32 #include "key_event.h"
34 #include "tzsh_volume_service.h"
36 #define VCONF_KEY_FMRADIO_RECORDING "memory/private/Sound/FMRadioRecording"
38 struct _control_s_info{
39 bundle *volume_bundle;
41 Eina_Bool is_deleting;
42 Eina_Bool is_launching;
44 Eina_Bool is_warning_visible;
52 sound_type_e sound_type_at_show;
54 static struct _control_s_info control_info = {
55 .volume_bundle = NULL,
57 .is_deleting = EINA_FALSE,
58 .is_launching = EINA_FALSE,
60 .is_warning_visible = EINA_FALSE,
61 .reset_once = EINA_FALSE,
62 .show_once = EINA_FALSE,
68 .sound_type_at_show = SOUND_TYPE_RINGTONE,
71 static void _notify_pm_lcdoff_cb(keynode_t * node, void *data);
72 static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data);
73 static void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data);
74 static void _control_set_window_rotation(Evas_Object *win);
75 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info);
77 bundle* volume_control_reset_get_bundle(void)
79 return control_info.volume_bundle;
82 Eina_Bool volume_control_get_is_deleting(void)
84 return control_info.is_deleting;
87 Eina_Bool volume_control_get_is_launching(void)
89 return control_info.is_launching;
92 int volume_control_get_current_angle(void)
94 return control_info.current_angle;
97 sound_type_e volume_control_get_sound_type_at_show(void)
99 return control_info.sound_type_at_show;
102 int volume_control_get_viewport_height()
104 return control_info.viewport_height;
107 int volume_control_get_viewport_width()
109 return control_info.viewport_width;
112 Eina_Bool volume_control_viewport_is_warning_visible()
114 return control_info.is_warning_visible;
117 volume_error_e volume_control_cache_flush(void)
119 Evas_Object *win = volume_view_win_get();
120 retv_if(win == NULL, VOLUME_ERROR_FAIL);
124 int collection_cache = -1;
125 int image_cache = -1;
128 evas = evas_object_evas_get(win);
129 retv_if(!evas, VOLUME_ERROR_FAIL);
131 file_cache = edje_file_cache_get();
132 collection_cache = edje_collection_cache_get();
133 image_cache = evas_image_cache_get(evas);
134 font_cache = evas_font_cache_get(evas);
136 edje_file_cache_set(file_cache);
137 edje_collection_cache_set(collection_cache);
138 evas_image_cache_set(evas, 0);
139 evas_font_cache_set(evas, 0);
141 evas_image_cache_flush(evas);
142 evas_render_idle_flush(evas);
143 evas_font_cache_flush(evas);
145 edje_file_cache_flush();
146 edje_collection_cache_flush();
148 edje_file_cache_set(file_cache);
149 edje_collection_cache_set(collection_cache);
150 evas_image_cache_set(evas, image_cache);
151 evas_font_cache_set(evas, font_cache);
153 return VOLUME_ERROR_OK;
156 /* rotation event callback func. */
157 volume_error_e volume_control_app_launch_with_bundle(const char *op_type, const char *operation, const char *pkgname)
159 app_control_h app_control;
162 ret = app_control_create(&app_control);
164 _E("Failed to create app control");
165 return VOLUME_ERROR_FAIL;
168 ret = app_control_set_app_id(app_control, pkgname);
171 _E("Failed to set appid");
172 app_control_destroy(app_control);
173 return VOLUME_ERROR_FAIL;
176 ret = app_control_add_extra_data(app_control, op_type, operation);
179 _E("Failed to add extra data");
180 app_control_destroy(app_control);
181 return VOLUME_ERROR_FAIL;
184 ret = app_control_send_launch_request(app_control, NULL, NULL);
185 _D("launch app with service : [%s][%d]", pkgname, ret);
187 app_control_destroy(app_control);
189 return VOLUME_ERROR_OK;
192 int volume_control_get_vconf_idlelock(void)
194 int lock = IDLELOCK_OFF;
195 int pm_state = VCONFKEY_PM_STATE_NORMAL;
197 /* Check Idle-Lock */
198 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) < 0)
200 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
201 return IDLELOCK_ERROR;
203 _D("idlelock vconf : %d", lock);
206 if(vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
208 _E("Failed to get vconfkey : VCONFKEY_PM_STATE");
209 return IDLELOCK_ERROR;
211 _D("PM STATE vconf : %d", pm_state);
213 return (lock == VCONFKEY_IDLE_LOCK ||
214 pm_state == VCONFKEY_PM_STATE_LCDOFF ||
215 pm_state == VCONFKEY_PM_STATE_SLEEP
216 ) ? IDLELOCK_ON : IDLELOCK_OFF;
220 int volume_control_check_status(int *lock, sound_type_e *sound_type)
222 *lock = volume_control_get_vconf_idlelock();
223 *sound_type = volume_sound_sound_manager_type_get();
224 _D("lock : %d / sound_type : %d", *lock, *sound_type);
226 if(*lock == IDLELOCK_ON)
228 if(*sound_type == SOUND_TYPE_RINGTONE)
230 _D("IDLELOCK is ON / sound type is Ringtone");
231 return LOCK_AND_NOT_MEDIA;
234 if(*sound_type != SOUND_TYPE_RINGTONE)
236 _D("IDLELOCK is ON / sound type is not Ringtone(media or alaram)");
237 return LOCK_AND_MEDIA;
241 _D("IDLELOCK is OFF / normal case");
243 return UNLOCK_STATUS;
246 void volume_control_show_hide_worning()
248 Evas_Object *ly_outer = volume_view_outer_layout_get();
249 sound_type_e sound_type = volume_sound_sound_manager_type_get();
250 int volume = volume_sound_sound_manager_volume_get(sound_type);
252 if(sound_type == SOUND_TYPE_MEDIA
253 && volume>VOLUME_MAX_SAFETY_VOLUME_LEVEL)
255 if(!control_info.is_warning_visible)
257 control_info.is_warning_visible = EINA_TRUE;
259 if(control_info.current_angle == 90 || control_info.current_angle == 270)
261 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper"); //landscape
265 elm_object_signal_emit(ly_outer, "show_warning", "clipper"); //landscape
269 else if(control_info.is_warning_visible)
271 control_info.is_warning_visible = EINA_FALSE;
273 if(control_info.current_angle == 90 || control_info.current_angle == 270)
275 elm_object_signal_emit(ly_outer, "hide_warning_l", "clipper"); //landscape
279 elm_object_signal_emit(ly_outer, "hide_warning", "clipper"); //landscape
284 static Eina_Bool _volume_region_set_timer_cb(void *data)
286 Evas_Object *win = data;
288 volume_service_region_set(win, EINA_FALSE);
293 Eina_Bool volume_control_show_view(int status, sound_type_e sound_type, int sound, bool bt_opened)
295 _D("Volume control show");
296 Evas_Object *win = NULL;
299 sound_type_e pre_sound_type;
301 retv_if(control_info.is_deleting, EINA_FALSE);
303 control_info.is_new = EINA_TRUE;
305 win = volume_view_win_get();
306 retv_if(!win, EINA_FALSE);
308 pre_sound_type = volume_view_pre_sound_type_get();
310 if(status == LOCK_AND_NOT_MEDIA)
312 _D("Lock and Not Media");
313 if(evas_object_visible_get(win))
315 if(VOLUME_ERROR_OK != volume_control_hide_view())
317 _E("Failed to close volume");
320 if(VOLUME_ERROR_OK != volume_control_cache_flush())
322 _E("Failed to flush cache");
327 _D("UNLOCK or LOCK_AND_MEDIA");
328 control_info.sound_type_at_show = sound_type;
330 if (sound_type != pre_sound_type) {
331 if (VOLUME_ERROR_OK != volume_change_slider_max_value(sound_type)) {
332 _E("Failed to changed max volume");
336 if(status == UNLOCK_STATUS) {
337 if(VOLUME_ERROR_OK != volume_view_window_show(sound_type)) {
338 _E("Failed to show volume window");
340 ecore_timer_add(0.1f, _volume_region_set_timer_cb, win);
343 control_info.is_launching = EINA_TRUE;
345 if(bt_opened == 1 && sound_type == SOUND_TYPE_CALL)
347 _D("bt is opened and is calling");
348 volume = bt_get_bt_volume();
349 _D("bt volume is : %d", volume);
351 if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
353 _E("Failed to set volume value to slider");
358 volume = volume_sound_sound_manager_volume_get(sound_type);
359 _D("volume : %d", volume);
361 vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
362 _D("vibration : %d", vibration);
364 if(((vibration == 1 && sound == 0) || sound == 0) && sound_type == SOUND_TYPE_RINGTONE)
369 if(VOLUME_ERROR_OK != volume_view_slider_value_set(volume))
371 _E("Failed to set volume value to slider");
375 //@TODO: need to check
376 volume_view_volume_icon_set(sound_type, sound, vibration, bt_opened);
382 volume_error_e volume_control_close_bt_display(void)
384 retv_if(volume_control_get_is_deleting(), VOLUME_ERROR_FAIL);
386 _D("Start closing bt display");
388 control_info.is_deleting = EINA_TRUE;
391 if(VOLUME_ERROR_OK != volume_view_window_hide())
393 _E("Failed to hide window");
396 control_info.is_deleting = EINA_FALSE;
398 _D("End closing bt display");
399 volume_timer_del(TYPE_TIMER_BT);
404 volume_error_e volume_control_hide_view(void)
406 retv_if(volume_control_get_is_deleting(), VOLUME_ERROR_FAIL);
408 _D("Start closing volume view");
410 control_info.is_deleting = EINA_TRUE;
412 volume_timer_del(TYPE_TIMER_SU);
413 volume_timer_del(TYPE_TIMER_SD);
414 volume_timer_del(TYPE_TIMER_SLIDER);
415 volume_timer_del(TYPE_TIMER_POPUP);
418 if (VOLUME_ERROR_OK != volume_view_window_hide()) {
419 _E("Failed to hide window");
422 control_info.is_deleting = EINA_FALSE;
423 control_info.is_launching = EINA_FALSE;
425 _D("End closing volume view");
430 void volume_control_register_vconfkey(void)
432 /* other app grab volume key => close volume */
433 if(vconf_notify_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb, NULL) != 0)
435 _E("Failed to register callback function : VCONFKEY_STARTER_USE_VOLUME_KEY");
438 /* Lock screen status vconf changed callback */
439 if(vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb, NULL) != 0)
441 _E("Failed to notify vconfkey : VCONFKEY_IDLE_LOCK_STATE");
444 if (vconf_notify_key_changed(VCONFKEY_PM_LCDOFF_SOURCE, _notify_pm_lcdoff_cb, NULL) != 0) {
445 _E("Failed to notify vconfkey : VCONFKEY_PM_LCDOFF_SOURCE");
449 void volume_control_unregister_vconfkey(void)
451 /* other app grab volume key => close volume */
452 if(vconf_ignore_key_changed(VCONFKEY_STARTER_USE_VOLUME_KEY, _starter_user_volume_key_vconf_changed_cb) < 0)
454 _E("Failed to ignore vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
457 /* Lock screen status vconf changed callback */
458 if(vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE, _idle_lock_state_vconf_changed_cb) < 0)
460 _E("Failed to ignore vconfkey : VCONFKEY_IDLE_LOCK_STATE");
463 if (vconf_ignore_key_changed
464 (VCONFKEY_PM_LCDOFF_SOURCE, _notify_pm_lcdoff_cb) != 0) {
465 _E("Fail vconf_ignore_key_changed : VCONFKEY_PM_LCDOFF_SOURCE");
469 volume_error_e volume_control_pause(void)
471 Evas_Object *win = volume_view_win_get();
472 retv_if(!win, VOLUME_ERROR_FAIL);
474 if(evas_object_visible_get(win)) {
475 if(VOLUME_ERROR_OK != volume_control_hide_view())
477 _E("Failed to close volume");
480 if(VOLUME_ERROR_OK != volume_control_cache_flush())
482 _E("Failed to flush cache");
486 return VOLUME_ERROR_OK;
489 volume_error_e volume_control_reset(bundle *b)
491 _D("Volume control reset");
492 Evas_Object *win = volume_view_win_get();
493 retv_if(!win, VOLUME_ERROR_FAIL);
495 int lock = IDLELOCK_ON;
500 bool bt_opened = false;
501 sound_type_e sound_type = 0;
502 const char *show_volume = NULL;
504 status = volume_control_check_status(&lock, &sound_type);
505 _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
507 volume = volume_sound_sound_manager_volume_get(sound_type);
508 _D("volume : %d", volume);
510 sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
511 _D("sound status : %d", sound);
513 error = bt_ag_is_sco_opened(&bt_opened);
514 if(error != BT_ERROR_NONE)
516 _E("bt_ag_is_sco_opened return [%d]", error);
518 _D("BT state %d", bt_opened);
520 show_volume = bundle_get_val(b, SHOWVOLUME);
521 retv_if(!show_volume, VOLUME_ERROR_FAIL);
523 if(!strncasecmp(show_volume, ISTRUE, strlen(ISTRUE)))
525 _D("Bundle : %s", show_volume);
526 if(lock == IDLELOCK_OFF)
529 volume_timer_add(3.0, TYPE_TIMER_POPUP);
530 volume_control_show_view(status, sound_type, sound, bt_opened);
534 return VOLUME_ERROR_OK;
537 volume_error_e volume_control_initialize(void)
539 _D("Volume control initialize");
541 /* Create main window */
542 Evas_Object *win = volume_view_window_create();
543 retv_if(!win, VOLUME_ERROR_FAIL);
545 /* Create volume layout */
546 if(VOLUME_ERROR_OK != volume_view_layout_create(win)) {
547 _E("Failed to create volume layout");
548 return VOLUME_ERROR_FAIL;
551 elm_win_screen_size_get(win, NULL, NULL, &(control_info.viewport_width), &(control_info.viewport_height));
553 /* Set available rotations */
554 _control_set_window_rotation(win);
556 /* Register vconfkey changed callback
557 * : VCONFKEY_STARTER_USE_VOLUME_KEY
558 * : VCONFKEY_IDLE_LOCK_STATE
559 * : VCONFKEY_LOCKSCREEN_SVIEW_STATE
561 volume_control_register_vconfkey();
563 /* Register vconfkey changed callback
564 * : VCONFKEY_SETAPPL_SOUND_STATUS_BOOL
565 * : VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL
567 volume_sound_vconfkey_register();
569 /* Add key event handler */
570 volume_key_event_handler_add();
572 /* Register volume changed callback */
573 volume_sound_mm_sound_init();
575 /* BT initialize and register changed callback */
578 return VOLUME_ERROR_OK;
581 void volume_control_deinitialize(void)
583 /* Unregister vconfkey changed callback */
584 volume_control_unregister_vconfkey();
586 /* Unregister sound vconfkey changed callback */
587 volume_sound_vconfkey_unregister();
589 /* Unregister bt changed callback */
593 void volume_service_region_set(Evas_Object *win, Eina_Bool is_warning_visible)
595 _D("X input event shape");
596 Evas_Object *ly = NULL;
598 tzsh_volume_service_h volume_service = NULL;
599 tzsh_region_h rect = NULL;
608 tzsh = volume_view_tzsh_get();
610 volume_service = volume_view_service_get();
611 ret_if(!volume_service);
613 int current_angle = volume_control_get_current_angle();
614 _D("Current angle : %d", current_angle);
616 ly = volume_view_outer_layout_get();
618 _E("Failed to load edje");
622 edje_object_part_geometry_get(_EDJ(ly), "bg", &x, &y, &w, &h);
623 _D("The position of bg x: %d, y: %d, w: %d, h: %d", x, y, w, h);
625 if (current_angle == 90) {
636 else if (current_angle == 270) {
642 x = volume_control_get_viewport_width()-tmp_y-tmp_h;
648 rect = tzsh_region_create(tzsh);
650 tzsh_region_add(rect, x, y, w, h);
651 _D("shape x: %d, y: %d, w: %d, h: %d", x, y, w, h);
652 ret = tzsh_volume_service_content_region_set(volume_service, current_angle, rect);
653 _D("The result of volume region set is : %d", ret);
654 tzsh_region_destroy(rect);
657 static void _rotate_changed_cb(void *data, Evas_Object *obj, void *event_info)
659 static int current_angle = -1;
660 int changed_angle = elm_win_rotation_get(obj);
663 Evas_Object *ly_outer = volume_view_outer_layout_get();
666 _D("window rotated [%d] => [%d]", current_angle, changed_angle);
667 if(current_angle != changed_angle) {
668 current_angle = changed_angle;
669 control_info.current_angle = current_angle;
670 switch(current_angle){
673 _D("show,landscape");
674 elm_object_signal_emit(ly_outer, "show,landscape", "bg");
675 if(control_info.is_warning_visible)
677 elm_object_signal_emit(ly_outer, "show_warning_l", "clipper");
682 elm_object_signal_emit(ly_outer, "show,portrait", "bg");
683 if(control_info.is_warning_visible)
685 elm_object_signal_emit(ly_outer, "show_warning", "clipper");
690 volume_service_region_set(obj, control_info.is_warning_visible);
694 static void _control_set_window_rotation(Evas_Object *win)
698 if (elm_win_wm_rotation_supported_get(win)) {
699 const int rots[4] = { 0, 90, 180, 270 };
700 elm_win_wm_rotation_available_rotations_set(win, (const int *)&rots, 4);
701 _D("set available rotations");
704 /* rotation event callback */
705 evas_object_smart_callback_add(win, "wm,rotation,changed", _rotate_changed_cb, NULL);
707 /* initialize degree */
708 _rotate_changed_cb(NULL, win, NULL);
711 static void _starter_user_volume_key_vconf_changed_cb(keynode_t *key, void *data)
713 int ret = EINA_FALSE;
715 if(vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &ret) < 0)
717 _E("Failed to get vconfkey : VCONFKEY_STARTER_USE_VOLUME_KEY");
724 _D("any other App grab volume hard key");
725 if(VOLUME_ERROR_OK != volume_control_hide_view()) {
726 _E("Failed to close volume");
729 if(VOLUME_ERROR_OK != volume_control_cache_flush()) {
730 _E("Failed to flush cache");
733 if(vconf_set_int(VCONFKEY_STARTER_USE_VOLUME_KEY, 0) < 0) {
734 _E("Failed to get vconfkey : VCONFKEY_STATER_USE_VOLUME_KEY");
740 _D("setting App grab volume hard key");
744 static void _idle_lock_state_vconf_changed_cb(keynode_t *key, void *data)
746 int lock = VCONFKEY_IDLE_UNLOCK;
748 if(vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock) < 0)
750 _E("Failed to get vconfkey : VCONFKEY_IDLE_LOCK_STATE");
753 _D("idle lock state : %d", lock);
755 if(lock == VCONFKEY_IDLE_LAUNCHING_LOCK)
757 if(VOLUME_ERROR_OK != volume_view_window_hide())
759 _E("Failed to hide window");
764 static void _notify_pm_lcdoff_cb(keynode_t * node, void *data)
766 if(VOLUME_ERROR_OK != volume_control_hide_view())
768 _E("Failed to close volume");
771 if(VOLUME_ERROR_OK != volume_control_cache_flush())
773 _E("Failed to flush cache");