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);
135 earphone_connected = earphone_get_earphone_is_connected();
137 _D("BT state %d, Earphone state: %d", bt_opened, earphone_connected);
139 volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
141 if (sound_type == SOUND_TYPE_MEDIA) {
142 if (key_event_info.is_mute == EINA_FALSE) {
143 _D("media is playing. set media volume to 0.");
144 lastval = volume_sound_level_get(sound_type);
145 retv_if(lastval == -1, VOLUME_ERROR_FAIL);
147 key_event_info.last_value_in_media = lastval;
148 volume_sound_level_set(sound_type, 0);
149 if (VOLUME_ERROR_OK != volume_view_slider_value_set(0)) {
150 _E("Failed to set slider value");
151 return VOLUME_ERROR_FAIL;
153 key_event_info.is_mute = EINA_TRUE;
154 return VOLUME_ERROR_OK;
156 _D("toggle the mute key to normal in media. last value in media : %d", key_event_info.last_value_in_media);
157 volume_sound_level_set(sound_type, lastval);
158 if (VOLUME_ERROR_OK != volume_view_slider_value_set(lastval)) {
159 _E("Failed to set slider value");
160 return VOLUME_ERROR_FAIL;
162 key_event_info.is_mute = EINA_FALSE;
163 return VOLUME_ERROR_OK;
166 if (lock == IDLELOCK_ON) {
167 _D("lock is on, block the MUTE key");
168 return VOLUME_ERROR_OK;
171 if (volume_mute_toggle_set())
172 volume_sound_feedback_play(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_GENERAL);
174 return VOLUME_ERROR_OK;
178 static volume_error_e _volume_up_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
184 _D("Volume Up Key Pressed");
185 key_event_info.is_mute = EINA_FALSE;
187 sound_step = volume_sound_step_get();
188 _D("sound step : %d", sound_step);
190 sound_level = volume_sound_level_get(sound_type);
191 retv_if(sound_level == -1, VOLUME_ERROR_FAIL);
192 _D("sound level : %d", sound_level);
194 vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
195 _D("vibration : %d", vibration);
197 if (elm_object_disabled_get(volume_view_slider_get()))
198 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
200 if (sound_type == SOUND_TYPE_RINGTONE) {
202 /* Check sound status change case. */
205 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
206 volume_sound_vib_play();
210 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
211 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
212 volume_sound_level_set(sound_type, sound_level+1);
213 volume_view_slider_value_set(sound_level+1);
214 _D("new sound value: %d", sound_level+1);
218 /*adjust the sound level normally */
219 if (sound_level != sound_step) {
220 volume_sound_level_set(sound_type, sound_level+1);
221 volume_view_slider_value_set(sound_level+1);
222 _D("new sound value: %d", sound_level+1);
226 else if (sound_type == SOUND_TYPE_NOTIFICATION) {
228 /* No sound in notification type. */
229 volume_view_slider_value_set(0);
230 elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
233 /*adjust the sound level normally */
234 if (sound_level != sound_step) {
235 volume_sound_level_set(sound_type, sound_level+1);
236 volume_view_slider_value_set(sound_level+1);
237 _D("new sound value: %d", sound_level+1);
241 /* Sound type is not ringtone. Need to adjust sound level */
242 else if (sound_type == SOUND_TYPE_CALL && bt_opened) {
244 if (bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
245 _E("Getting bt volume is failed");
247 _D("BT VOLUME : %d", bt_vol);
249 if (bt_vol != sound_step) {
250 if(bt_ag_notify_speaker_gain(bt_vol+1) != BT_ERROR_NONE)
251 _E("Setting bt volume is failed");
252 volume_view_slider_value_set(bt_vol+1);
253 _D("New BT VOLUME : %d", bt_vol+1);
257 if (sound_type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected) && sound_level + 1 > SAFETY_LIMIT) {
258 if (volume_control_get_safety_limit()) {
259 display_state_e state;
260 volume_sound_level_set(sound_type, SAFETY_LIMIT);
261 volume_view_slider_value_set(SAFETY_LIMIT);
262 if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE)) {
263 _E("Failed to set warning status");
265 if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
266 _E("Failed to open waring popup!!");
267 return VOLUME_ERROR_FAIL;
269 if (device_display_get_state(&state) != DEVICE_ERROR_NONE) {
270 _E("Failed to get display state");
272 if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
273 device_display_change_state(DISPLAY_STATE_NORMAL);
274 if(FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_WAKEUP)) {
275 _E("Failed to play vibration");
278 if (status == LOCK_AND_MEDIA) {
280 volume_view_window_show(sound_type);
282 volume_timer_del(TYPE_TIMER_SU);
283 volume_timer_del(TYPE_TIMER_SD);
284 volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
285 return VOLUME_ERROR_OK;
288 if (sound_level != sound_step) {
289 volume_sound_level_set(sound_type, sound_level+1);
290 volume_view_slider_value_set(sound_level+1);
291 _D("new sound value: %d", sound_level+1);
295 if (sound_type != SOUND_TYPE_ALARM)
298 volume_timer_del(TYPE_TIMER_SU);
299 volume_timer_del(TYPE_TIMER_SD);
300 volume_timer_add(0.5, TYPE_TIMER_SU);
302 if (!volume_timer_su_timer_get()) {
303 _E("Failed to get SUTIMER");
304 return VOLUME_ERROR_FAIL;
307 return VOLUME_ERROR_OK;
310 static volume_error_e _volume_down_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
312 key_event_info.is_mute = EINA_FALSE;
314 int val = volume_sound_level_get(sound_type);
315 retv_if(val == -1, VOLUME_ERROR_FAIL);
317 int sound_st = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
318 _D("sound status : %d", sound_st);
320 int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
321 _D("vibration : %d", vibration);
323 if (elm_object_disabled_get(volume_view_slider_get()))
324 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
326 if(sound_type == SOUND_TYPE_RINGTONE){
328 /* Check sound status change case. */
332 volume_sound_level_set(sound_type, val - 1);
333 volume_view_slider_value_set(val - 1);
334 /*adjust the sound level normally */
336 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
337 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
338 volume_sound_vib_play();
343 else if (sound_type == SOUND_TYPE_NOTIFICATION) {
345 /* No sound in notification type. */
346 volume_view_slider_value_set(0);
347 elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
350 /*adjust the sound level normally */
352 volume_sound_level_set(sound_type, val-1);
353 volume_view_slider_value_set(val-1);
354 _D("new sound value: %d", val-1);
358 else if(sound_type == SOUND_TYPE_CALL && bt_opened) {
360 if(bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
361 _E("Getting bt volume is failed");
363 _D("BT VOLUME : %d", bt_vol);
364 if(bt_ag_notify_speaker_gain(bt_vol-1) != BT_ERROR_NONE)
365 _E("Setting bt volume is failed");
366 volume_view_slider_value_set(bt_vol-1);
368 _D("New BT VOLUME : %d", bt_vol-1);
370 /* Sound type is not ringtone. Need to adjust sound level */
372 if (volume_control_get_safety_limit() && sound_type == SOUND_TYPE_MEDIA
373 && (bt_opened || earphone_connected) && val > SAFETY_LIMIT) {
374 display_state_e state;
375 volume_sound_level_set(sound_type, SAFETY_LIMIT);
376 volume_view_slider_value_set(SAFETY_LIMIT);
377 if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE)) {
378 _E("Failed to set warning status");
380 if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
381 _E("Failed to open waring popup!!");
382 return VOLUME_ERROR_FAIL;
384 if (device_display_get_state(&state) != DEVICE_ERROR_NONE) {
385 _E("Failed to get display state");
387 if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
388 device_display_change_state(DISPLAY_STATE_NORMAL);
389 if(FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_WAKEUP)) {
390 _E("Failed to play vibration");
393 if (status == LOCK_AND_MEDIA) {
395 volume_view_window_show(sound_type);
397 volume_timer_del(TYPE_TIMER_SU);
398 volume_timer_del(TYPE_TIMER_SD);
399 volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
400 } else if (val != 0) {
401 volume_sound_level_set(sound_type, val - 1);
402 volume_view_slider_value_set(val - 1);
403 _D("new sound value: %d", val-1);
407 if(sound_type != SOUND_TYPE_ALARM)
410 volume_timer_del(TYPE_TIMER_SD);
411 volume_timer_del(TYPE_TIMER_SU);
412 volume_timer_add(0.5, TYPE_TIMER_SD);
414 return VOLUME_ERROR_OK;
417 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type)
421 if(sound_type == SOUND_TYPE_ALARM) {
422 _D("Sound type is Alarm Type");
423 if(vconf_get_bool(VCONFKEY_ALARM_VOLUME_POPUP_ENABLE, &is_enabled) < 0) {
424 _E("Failed to get vconfkey : VCONFKEY_ALARM_VOLUME_POPUP_ENABLE");
425 return VOLUME_ERROR_FAIL;
427 _D("volume popup enabled in alarm type : %d", is_enabled);
430 _D("alarm type but vconf for the volume popup is disabled");
431 return VOLUME_ERROR_FAIL;
435 return VOLUME_ERROR_OK;
438 static Eina_Bool _key_press_cb(void *data, int type, void *event)
441 int lock = IDLELOCK_ON;
445 int earphone_connected = 0;
446 bool bt_opened = false;
447 sound_type_e sound_type = 0;
448 Evas_Object *win = NULL;
449 Ecore_Event_Key *ev = NULL;
451 ev = (Ecore_Event_Key*) event;
452 retv_if(!ev, ECORE_CALLBACK_CANCEL);
454 _D("Key Press CB : %s", ev->keyname);
456 win = volume_view_win_get();
457 retv_if(!win, ECORE_CALLBACK_CANCEL);
459 if (volume_view_warning_popup_get()) {
460 _D("Safety warning popup is exist");
461 return ECORE_CALLBACK_CANCEL;
464 if (!volume_control_get_safety_limit() && volume_control_get_time_for_safety_limit()) {
465 _D("Already passed 20 hour after checking warning popup, open warning again");
466 volume_control_set_safety_limit(EINA_TRUE);
469 if(!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL)) || !strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
470 _D("%s is pressed", ev->keyname);
471 return ECORE_CALLBACK_CANCEL;
474 if(volume_view_is_slider_touching_get()) {
475 _E("Failed to show volume : is_slider_touching is EINA_TRUE");
476 return ECORE_CALLBACK_CANCEL;
479 if(vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &key_status) < 0) {
480 _E("Failed to get vconf : VCONFKEY_STATER_USE_VOLUME_KEY");
481 return ECORE_CALLBACK_CANCEL;
483 retvm_if(key_status == 2, ECORE_CALLBACK_CANCEL, "starter use volume key. status : 2");
487 if(!strncmp(ev->keyname, KEY_MUTE, strlen(KEY_MUTE))) {
488 _D("MUTE key is pressed");
489 if(VOLUME_ERROR_OK != _mute_key_press())
490 _E("Failed to press MUTE key");
491 return ECORE_CALLBACK_CANCEL;
494 if(vconf_get_int(VCONFKEY_TELEPHONY_CALL_STATE, &is_call) < 0 || is_call < 0) {
495 _E("Failed to get call state vconf");
496 return ECORE_CALLBACK_CANCEL;
499 _D("Call is active");
500 return ECORE_CALLBACK_CANCEL;
504 status = volume_control_check_status(&lock, &sound_type);
505 _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
507 sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
508 _D("sound status : %d", sound);
510 error = bt_ag_is_sco_opened(&bt_opened);
511 if(error != BT_ERROR_NONE) {
512 _E("bt_ag_is_sco_opened return [%d]", error);
514 earphone_connected = earphone_get_earphone_is_connected();
515 _D("module state - bt: %d, earphone: %d", bt_opened, earphone_connected);
517 if(VOLUME_ERROR_OK != _volume_popup_check_in_alarm_type(sound_type)) {
518 _E("Failed to set volume popup");
519 return ECORE_CALLBACK_CANCEL;
522 volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
524 key_event_info.is_pressing = EINA_TRUE;
526 volume_timer_del(TYPE_TIMER_POPUP);
528 if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
529 if(VOLUME_ERROR_OK != _volume_up_key_press(status, sound_type, sound, bt_opened, earphone_connected))
530 _E("Failed to press volume up key");
532 else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
533 if(VOLUME_ERROR_OK != _volume_down_key_press(status, sound_type, sound, bt_opened, earphone_connected))
534 _E("Failed to press volume down key");
537 return ECORE_CALLBACK_CANCEL;
540 static Eina_Bool _key_release_cb(void *data, int type, void *event)
542 Ecore_Event_Key *ev = event;
543 retv_if(ev == NULL, ECORE_CALLBACK_CANCEL);
544 _D("Key Release CB : %s", ev->keyname);
546 Evas_Object *win = volume_view_win_get();
547 retv_if(win == NULL, ECORE_CALLBACK_CANCEL);
549 key_event_info.is_pressing = EINA_FALSE;
551 if(!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL))) {
552 _D("%s is released", ev->keyname);
553 if(VOLUME_ERROR_OK != volume_control_hide_view())
554 _E("Failed to close volume");
555 if(VOLUME_ERROR_OK != volume_control_cache_flush())
556 _E("Failed to flush cache");
557 return ECORE_CALLBACK_CANCEL;
560 if(!strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
561 _D("BACK Key is released");
562 return ECORE_CALLBACK_CANCEL;
565 if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
566 _D("up key released and del timer");
567 volume_timer_del(TYPE_TIMER_SU);
569 else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
570 _D("down key released and del timer");
571 volume_timer_del(TYPE_TIMER_SD);
574 volume_timer_del(TYPE_TIMER_POPUP);
576 if(volume_view_is_slider_touching_get() == EINA_FALSE) {
577 if (!volume_view_warning_popup_get()) {
578 volume_timer_add(3.0, TYPE_TIMER_POPUP);
582 _D("key release fini");
583 return ECORE_CALLBACK_CANCEL;