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.
19 #include <vconf-keys.h>
21 #include <bluetooth.h>
22 #include <bluetooth_internal.h>
23 #include <bluetooth_extension.h>
24 #include <device/display.h>
27 #include "_util_log.h"
28 #include "_util_efl.h"
33 #include "key_event.h"
37 #define VCONFKEY_ALARM_VOLUME_POPUP_ENABLE "memory/alarm/volume_popup_enable"
38 #define VOLUME_INPUT_WIN_NAME "volumekey-input-window"
39 #define SAFETY_LIMIT 9
41 struct _key_event_s_info {
42 Ecore_X_Window input_win;
44 Ecore_Event_Handler *handler_volume_up;
45 Ecore_Event_Handler *handler_volume_down;
46 Ecore_Event_Handler *handler_qp_state_check;
49 Eina_Bool is_pressing;
53 int last_value_in_media;
56 static struct _key_event_s_info key_event_info = {
59 .handler_volume_up = NULL,
60 .handler_volume_down = NULL,
61 .handler_qp_state_check = NULL,
63 .is_mute = EINA_FALSE,
64 .is_pressing = EINA_FALSE,
68 .last_value_in_media = 0,
71 static Eina_Bool _key_release_cb(void *data, int type, void *event);
72 static Eina_Bool _key_press_cb(void *data, int type, void *event);
73 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type);
74 static volume_error_e _volume_down_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected);
75 static volume_error_e _volume_up_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected);
76 static volume_error_e _mute_key_press();
78 Ecore_Event_Handler* volume_key_event_handler_volume_up_get(void)
80 return key_event_info.handler_volume_up;
83 Ecore_Event_Handler* volume_key_event_handler_volume_down_get(void)
85 return key_event_info.handler_volume_down;
88 Eina_Bool volume_key_event_is_pressing_get(void)
90 return key_event_info.is_pressing;
93 void volume_key_event_handler_add(void)
95 if (!key_event_info.handler_volume_up)
96 key_event_info.handler_volume_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
98 if (!key_event_info.handler_volume_down)
99 key_event_info.handler_volume_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
102 void volume_key_event_handler_del(void)
104 ret_if(key_event_info.handler_volume_up == NULL);
105 ecore_event_handler_del(key_event_info.handler_volume_up);
106 key_event_info.handler_volume_up = NULL;
108 ret_if(key_event_info.handler_volume_down == NULL);
109 ecore_event_handler_del(key_event_info.handler_volume_down);
110 key_event_info.handler_volume_down = NULL;
113 static volume_error_e _mute_key_press()
116 int lock = IDLELOCK_ON;
120 int earphone_connected = 0;
121 bool bt_opened = false;
122 sound_type_e sound_type = 0;
124 status = volume_control_check_status(&lock, &sound_type);
125 _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
127 sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
128 _D("sound status : %d", sound);
130 error = bt_ag_is_sco_opened(&bt_opened);
131 if (error != BT_ERROR_NONE)
132 _E("bt_ag_is_sco_opened return [%d]", error);
134 earphone_connected = earphone_get_earphone_is_connected();
136 _D("BT state %d, Earphone state: %d", bt_opened, earphone_connected);
138 volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
140 if (sound_type == SOUND_TYPE_MEDIA) {
141 if (key_event_info.is_mute == EINA_FALSE) {
142 _D("media is playing. set media volume to 0.");
143 lastval = volume_sound_level_get(sound_type);
144 retv_if(lastval == -1, VOLUME_ERROR_FAIL);
146 key_event_info.last_value_in_media = lastval;
147 volume_sound_level_set(sound_type, 0);
148 if (VOLUME_ERROR_OK != volume_view_slider_value_set(0)) {
149 _E("Failed to set slider value");
150 return VOLUME_ERROR_FAIL;
152 key_event_info.is_mute = EINA_TRUE;
153 return VOLUME_ERROR_OK;
155 _D("toggle the mute key to normal in media. last value in media : %d", key_event_info.last_value_in_media);
156 volume_sound_level_set(sound_type, lastval);
157 if (VOLUME_ERROR_OK != volume_view_slider_value_set(lastval)) {
158 _E("Failed to set slider value");
159 return VOLUME_ERROR_FAIL;
161 key_event_info.is_mute = EINA_FALSE;
162 return VOLUME_ERROR_OK;
165 if (lock == IDLELOCK_ON) {
166 _D("lock is on, block the MUTE key");
167 return VOLUME_ERROR_OK;
170 if (volume_mute_toggle_set())
171 volume_sound_feedback_play(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_GENERAL);
173 return VOLUME_ERROR_OK;
177 static volume_error_e _volume_up_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
183 _D("Volume Up Key Pressed");
184 key_event_info.is_mute = EINA_FALSE;
186 sound_step = volume_sound_step_get();
187 _D("sound step : %d", sound_step);
189 sound_level = volume_sound_level_get(sound_type);
190 retv_if(sound_level == -1, VOLUME_ERROR_FAIL);
191 _D("sound level : %d", sound_level);
193 vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
194 _D("vibration : %d", vibration);
196 if (elm_object_disabled_get(volume_view_slider_get()))
197 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
199 if (sound_type == SOUND_TYPE_RINGTONE) {
201 /* Check sound status change case. */
204 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
205 volume_sound_vib_play();
208 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
209 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
210 volume_sound_level_set(sound_type, sound_level+1);
211 volume_view_slider_value_set(sound_level+1);
212 _D("new sound value: %d", sound_level+1);
215 /*adjust the sound level normally */
216 if (sound_level != sound_step) {
217 volume_sound_level_set(sound_type, sound_level+1);
218 volume_view_slider_value_set(sound_level+1);
219 _D("new sound value: %d", sound_level+1);
222 } else if (sound_type == SOUND_TYPE_NOTIFICATION) {
224 /* No sound in notification type. */
225 volume_view_slider_value_set(0);
226 elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
228 /*adjust the sound level normally */
229 if (sound_level != sound_step) {
230 volume_sound_level_set(sound_type, sound_level+1);
231 volume_view_slider_value_set(sound_level+1);
232 _D("new sound value: %d", sound_level+1);
235 } else if (sound_type == SOUND_TYPE_CALL && bt_opened) {
236 /* Sound type is not ringtone. Need to adjust sound level */
238 if (bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
239 _E("Getting bt volume is failed");
241 _D("BT VOLUME : %d", bt_vol);
243 if (bt_vol != sound_step) {
244 if (bt_ag_notify_speaker_gain(bt_vol+1) != BT_ERROR_NONE)
245 _E("Setting bt volume is failed");
246 volume_view_slider_value_set(bt_vol+1);
247 _D("New BT VOLUME : %d", bt_vol+1);
250 if (sound_type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected) && sound_level + 1 > SAFETY_LIMIT) {
251 if (volume_control_get_safety_limit()) {
252 display_state_e state;
253 volume_sound_level_set(sound_type, SAFETY_LIMIT);
254 volume_view_slider_value_set(SAFETY_LIMIT);
255 if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE))
256 _E("Failed to set warning status");
258 if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
259 _E("Failed to open waring popup!!");
260 return VOLUME_ERROR_FAIL;
262 if (device_display_get_state(&state) != DEVICE_ERROR_NONE)
263 _E("Failed to get display state");
265 if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
266 device_display_change_state(DISPLAY_STATE_NORMAL);
267 if (FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_WAKEUP))
268 _E("Failed to play vibration");
270 if (status == LOCK_AND_MEDIA) {
272 volume_view_window_show(sound_type);
274 volume_timer_del(TYPE_TIMER_SU);
275 volume_timer_del(TYPE_TIMER_SD);
276 volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
277 return VOLUME_ERROR_OK;
280 if (sound_level != sound_step) {
281 volume_sound_level_set(sound_type, sound_level+1);
282 volume_view_slider_value_set(sound_level+1);
283 _D("new sound value: %d", sound_level+1);
287 if (sound_type != SOUND_TYPE_ALARM)
290 volume_timer_del(TYPE_TIMER_SU);
291 volume_timer_del(TYPE_TIMER_SD);
292 volume_timer_add(0.5, TYPE_TIMER_SU);
294 if (!volume_timer_su_timer_get()) {
295 _E("Failed to get SUTIMER");
296 return VOLUME_ERROR_FAIL;
299 return VOLUME_ERROR_OK;
302 static volume_error_e _volume_down_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
304 key_event_info.is_mute = EINA_FALSE;
306 int val = volume_sound_level_get(sound_type);
307 retv_if(val == -1, VOLUME_ERROR_FAIL);
309 int sound_st = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
310 _D("sound status : %d", sound_st);
312 int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
313 _D("vibration : %d", vibration);
315 if (elm_object_disabled_get(volume_view_slider_get()))
316 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
318 if (sound_type == SOUND_TYPE_RINGTONE) {
320 /* Check sound status change case. */
324 volume_sound_level_set(sound_type, val - 1);
325 volume_view_slider_value_set(val - 1);
326 /*adjust the sound level normally */
328 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
329 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
330 volume_sound_vib_play();
334 } else if (sound_type == SOUND_TYPE_NOTIFICATION) {
336 /* No sound in notification type. */
337 volume_view_slider_value_set(0);
338 elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
340 /*adjust the sound level normally */
342 volume_sound_level_set(sound_type, val-1);
343 volume_view_slider_value_set(val-1);
344 _D("new sound value: %d", val-1);
347 } else if (sound_type == SOUND_TYPE_CALL && bt_opened) {
349 if (bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
350 _E("Getting bt volume is failed");
352 _D("BT VOLUME : %d", bt_vol);
353 if (bt_ag_notify_speaker_gain(bt_vol-1) != BT_ERROR_NONE)
354 _E("Setting bt volume is failed");
355 volume_view_slider_value_set(bt_vol-1);
357 _D("New BT VOLUME : %d", bt_vol-1);
359 /* Sound type is not ringtone. Need to adjust sound level */
360 if (volume_control_get_safety_limit() && sound_type == SOUND_TYPE_MEDIA
361 && (bt_opened || earphone_connected) && val > SAFETY_LIMIT) {
362 display_state_e state;
363 volume_sound_level_set(sound_type, SAFETY_LIMIT);
364 volume_view_slider_value_set(SAFETY_LIMIT);
365 if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE))
366 _E("Failed to set warning status");
368 if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
369 _E("Failed to open waring popup!!");
370 return VOLUME_ERROR_FAIL;
372 if (device_display_get_state(&state) != DEVICE_ERROR_NONE)
373 _E("Failed to get display state");
375 if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
376 device_display_change_state(DISPLAY_STATE_NORMAL);
377 if (FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_WAKEUP))
378 _E("Failed to play vibration");
380 if (status == LOCK_AND_MEDIA)
382 volume_view_window_show(sound_type);
384 volume_timer_del(TYPE_TIMER_SU);
385 volume_timer_del(TYPE_TIMER_SD);
386 volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
387 } else if (val != 0) {
388 volume_sound_level_set(sound_type, val - 1);
389 volume_view_slider_value_set(val - 1);
390 _D("new sound value: %d", val-1);
394 if (sound_type != SOUND_TYPE_ALARM)
397 volume_timer_del(TYPE_TIMER_SD);
398 volume_timer_del(TYPE_TIMER_SU);
399 volume_timer_add(0.5, TYPE_TIMER_SD);
401 return VOLUME_ERROR_OK;
404 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type)
408 if (sound_type == SOUND_TYPE_ALARM) {
409 _D("Sound type is Alarm Type");
410 if (vconf_get_bool(VCONFKEY_ALARM_VOLUME_POPUP_ENABLE, &is_enabled) < 0) {
411 _E("Failed to get vconfkey : VCONFKEY_ALARM_VOLUME_POPUP_ENABLE");
412 return VOLUME_ERROR_FAIL;
414 _D("volume popup enabled in alarm type : %d", is_enabled);
417 _D("alarm type but vconf for the volume popup is disabled");
418 return VOLUME_ERROR_FAIL;
422 return VOLUME_ERROR_OK;
425 static Eina_Bool _key_press_cb(void *data, int type, void *event)
428 int lock = IDLELOCK_ON;
432 int earphone_connected = 0;
433 bool bt_opened = false;
434 sound_type_e sound_type = 0;
435 Evas_Object *win = NULL;
436 Ecore_Event_Key *ev = NULL;
438 ev = (Ecore_Event_Key*) event;
439 retv_if(!ev, ECORE_CALLBACK_CANCEL);
441 _D("Key Press CB : %s", ev->keyname);
443 win = volume_view_win_get();
444 retv_if(!win, ECORE_CALLBACK_CANCEL);
446 if (volume_view_warning_popup_get()) {
447 _D("Safety warning popup is exist");
448 return ECORE_CALLBACK_CANCEL;
451 if (!volume_control_get_safety_limit() && volume_control_get_time_for_safety_limit()) {
452 _D("Already passed 20 hour after checking warning popup, open warning again");
453 volume_control_set_safety_limit(EINA_TRUE);
456 if (!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL)) || !strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
457 _D("%s is pressed", ev->keyname);
458 return ECORE_CALLBACK_CANCEL;
461 if (volume_view_is_slider_touching_get()) {
462 _E("Failed to show volume : is_slider_touching is EINA_TRUE");
463 return ECORE_CALLBACK_CANCEL;
466 if (vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &key_status) < 0) {
467 _E("Failed to get vconf : VCONFKEY_STATER_USE_VOLUME_KEY");
468 return ECORE_CALLBACK_CANCEL;
470 retvm_if(key_status == 2, ECORE_CALLBACK_CANCEL, "starter use volume key. status : 2");
473 if (!strncmp(ev->keyname, KEY_MUTE, strlen(KEY_MUTE))) {
474 _D("MUTE key is pressed");
475 if (VOLUME_ERROR_OK != _mute_key_press())
476 _E("Failed to press MUTE key");
477 return ECORE_CALLBACK_CANCEL;
481 status = volume_control_check_status(&lock, &sound_type);
482 _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
484 sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
485 _D("sound status : %d", sound);
487 error = bt_ag_is_sco_opened(&bt_opened);
488 if (error != BT_ERROR_NONE)
489 _E("bt_ag_is_sco_opened return [%d]", error);
491 earphone_connected = earphone_get_earphone_is_connected();
492 _D("module state - bt: %d, earphone: %d", bt_opened, earphone_connected);
494 if (VOLUME_ERROR_OK != _volume_popup_check_in_alarm_type(sound_type)) {
495 _E("Failed to set volume popup");
496 return ECORE_CALLBACK_CANCEL;
499 volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
501 key_event_info.is_pressing = EINA_TRUE;
503 volume_timer_del(TYPE_TIMER_POPUP);
505 if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
506 if (VOLUME_ERROR_OK != _volume_up_key_press(status, sound_type, sound, bt_opened, earphone_connected))
507 _E("Failed to press volume up key");
508 } else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
509 if (VOLUME_ERROR_OK != _volume_down_key_press(status, sound_type, sound, bt_opened, earphone_connected))
510 _E("Failed to press volume down key");
513 return ECORE_CALLBACK_CANCEL;
516 static Eina_Bool _key_release_cb(void *data, int type, void *event)
518 Ecore_Event_Key *ev = event;
519 retv_if(ev == NULL, ECORE_CALLBACK_CANCEL);
520 _D("Key Release CB : %s", ev->keyname);
522 Evas_Object *win = volume_view_win_get();
523 retv_if(win == NULL, ECORE_CALLBACK_CANCEL);
525 key_event_info.is_pressing = EINA_FALSE;
527 if (!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL))) {
528 _D("%s is released", ev->keyname);
529 if (VOLUME_ERROR_OK != volume_control_hide_view())
530 _E("Failed to close volume");
531 if (VOLUME_ERROR_OK != volume_control_cache_flush())
532 _E("Failed to flush cache");
533 return ECORE_CALLBACK_CANCEL;
536 if (!strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
537 _D("BACK Key is released");
538 return ECORE_CALLBACK_CANCEL;
541 if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
542 _D("up key released and del timer");
543 volume_timer_del(TYPE_TIMER_SU);
544 } else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
545 _D("down key released and del timer");
546 volume_timer_del(TYPE_TIMER_SD);
549 volume_timer_del(TYPE_TIMER_POPUP);
551 if (volume_view_is_slider_touching_get() == EINA_FALSE) {
552 if (!volume_view_warning_popup_get())
553 volume_timer_add(3.0, TYPE_TIMER_POPUP);
556 _D("key release fini");
557 return ECORE_CALLBACK_CANCEL;