Fix coverity issue 1149129
[apps/native/volume-app.git] / src / key_event.c
1 /*
2  * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <Ecore.h>
18 #include <vconf.h>
19 #include <vconf-keys.h>
20 #include <feedback.h>
21 #include <bluetooth.h>
22 #include <bluetooth_internal.h>
23 #include <bluetooth_extension.h>
24 #include <device/display.h>
25
26 #include "main.h"
27 #include "_util_log.h"
28 #include "_util_efl.h"
29 #include "view.h"
30 #include "control.h"
31 #include "sound.h"
32 #include "timer.h"
33 #include "key_event.h"
34 #include "bt.h"
35 #include "earphone.h"
36
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
40
41 struct _key_event_s_info {
42         Ecore_X_Window input_win;
43
44         Ecore_Event_Handler *handler_volume_up;
45         Ecore_Event_Handler *handler_volume_down;
46         Ecore_Event_Handler *handler_qp_state_check;
47
48         Eina_Bool is_mute;
49         Eina_Bool is_pressing;
50
51         int count_grabed;
52
53         int last_value_in_media;
54 };
55
56 static struct _key_event_s_info key_event_info = {
57         .input_win = 0,
58
59         .handler_volume_up = NULL,
60         .handler_volume_down = NULL,
61         .handler_qp_state_check = NULL,
62
63         .is_mute = EINA_FALSE,
64         .is_pressing = EINA_FALSE,
65
66         .count_grabed = 0,
67
68         .last_value_in_media = 0,
69 };
70
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();
77
78 Ecore_Event_Handler* volume_key_event_handler_volume_up_get(void)
79 {
80         return key_event_info.handler_volume_up;
81 }
82
83 Ecore_Event_Handler* volume_key_event_handler_volume_down_get(void)
84 {
85         return key_event_info.handler_volume_down;
86 }
87
88 Eina_Bool volume_key_event_is_pressing_get(void)
89 {
90         return key_event_info.is_pressing;
91 }
92
93 void volume_key_event_handler_add(void)
94 {
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);
97
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);
100 }
101
102 void volume_key_event_handler_del(void)
103 {
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;
107
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;
111 }
112
113 static volume_error_e _mute_key_press()
114 {
115         int lastval = -1;
116         int lock = IDLELOCK_ON;
117         int status = 0;
118         int sound = 0;
119         int error = 0;
120         int earphone_connected = 0;
121         bool bt_opened = false;
122         sound_type_e sound_type = 0;
123
124         status = volume_control_check_status(&lock, &sound_type);
125         _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
126
127         sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
128         _D("sound status : %d", sound);
129
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);
133
134         earphone_connected = earphone_get_earphone_is_connected();
135
136         _D("BT state %d, Earphone state: %d", bt_opened, earphone_connected);
137
138         volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
139
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);
145
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;
151                         }
152                         key_event_info.is_mute = EINA_TRUE;
153                         return VOLUME_ERROR_OK;
154                 } else {
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;
160                         }
161                         key_event_info.is_mute = EINA_FALSE;
162                         return VOLUME_ERROR_OK;
163                 }
164         } else {
165                 if (lock == IDLELOCK_ON) {
166                         _D("lock is on, block the MUTE key");
167                         return VOLUME_ERROR_OK;
168                 }
169
170                 if (volume_mute_toggle_set())
171                         volume_sound_feedback_play(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_GENERAL);
172
173                 return VOLUME_ERROR_OK;
174         }
175 }
176
177 static volume_error_e _volume_up_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
178 {
179         int sound_step = 0;
180         int sound_level = 0;
181         int vibration = 0;
182
183         _D("Volume Up Key Pressed");
184         key_event_info.is_mute = EINA_FALSE;
185
186         sound_step = volume_sound_step_get();
187         _D("sound step : %d", sound_step);
188
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);
192
193         vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
194         _D("vibration : %d", vibration);
195
196         if (elm_object_disabled_get(volume_view_slider_get()))
197                 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
198
199         if (sound_type == SOUND_TYPE_RINGTONE) {
200                 if (!sound) {
201                         /* Check sound status change case. */
202                         if (!vibration) {
203                                 _D("mute -> vib.");
204                                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
205                                 volume_sound_vib_play();
206                         } else {
207                                 _D("vib -> sound");
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);
213                         }
214                 } else {
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);
220                         }
221                 }
222         } else if (sound_type == SOUND_TYPE_NOTIFICATION) {
223                 if (!sound) {
224                         /* No sound in notification type. */
225                         volume_view_slider_value_set(0);
226                         elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
227                 } else {
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);
233                         }
234                 }
235         } else if (sound_type == SOUND_TYPE_CALL && bt_opened) {
236         /* Sound type is not ringtone. Need to adjust sound level */
237                 int bt_vol = 0;
238                 if (bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
239                         _E("Getting bt volume is failed");
240
241                 _D("BT VOLUME : %d", bt_vol);
242
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);
248                 }
249         } else {
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");
257
258                                 if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
259                                         _E("Failed to open waring popup!!");
260                                         return VOLUME_ERROR_FAIL;
261                                 }
262                                 if (device_display_get_state(&state) != DEVICE_ERROR_NONE)
263                                         _E("Failed to get display state");
264
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");
269                                 }
270                                 if (status == LOCK_AND_MEDIA) {
271                                         /* Check LCD */
272                                         volume_view_window_show(sound_type);
273                                 }
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;
278                         }
279                 }
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);
284                 }
285         }
286
287         if (sound_type != SOUND_TYPE_ALARM)
288                 volume_sound_play();
289
290         volume_timer_del(TYPE_TIMER_SU);
291         volume_timer_del(TYPE_TIMER_SD);
292         volume_timer_add(0.5, TYPE_TIMER_SU);
293
294         if (!volume_timer_su_timer_get()) {
295                 _E("Failed to get SUTIMER");
296                 return VOLUME_ERROR_FAIL;
297         }
298
299         return VOLUME_ERROR_OK;
300 }
301
302 static volume_error_e _volume_down_key_press(int status, sound_type_e sound_type, int sound, bool bt_opened, int earphone_connected)
303 {
304         key_event_info.is_mute = EINA_FALSE;
305
306         int val = volume_sound_level_get(sound_type);
307         retv_if(val == -1, VOLUME_ERROR_FAIL);
308
309         int sound_st = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
310         _D("sound status : %d", sound_st);
311
312         int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
313         _D("vibration : %d", vibration);
314
315         if (elm_object_disabled_get(volume_view_slider_get()))
316                 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
317
318         if (sound_type == SOUND_TYPE_RINGTONE) {
319                 if (!sound)
320                         /* Check sound status change case. */
321                         _D("Do nothing.");
322                 else {
323                         if (val != 0) {
324                                 volume_sound_level_set(sound_type, val - 1);
325                                 volume_view_slider_value_set(val - 1);
326                                 /*adjust the sound level normally */
327                                 if (val == 1) {
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();
331                                 }
332                         }
333                 }
334         } else if (sound_type == SOUND_TYPE_NOTIFICATION) {
335                 if (!sound) {
336                         /* No sound in notification type. */
337                         volume_view_slider_value_set(0);
338                         elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
339                 } else {
340                         /*adjust the sound level normally */
341                         if (val != 0) {
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);
345                         }
346                 }
347         } else if (sound_type == SOUND_TYPE_CALL && bt_opened) {
348                 int bt_vol = 0;
349                 if (bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
350                         _E("Getting bt volume is failed");
351
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);
356
357                 _D("New BT VOLUME : %d", bt_vol-1);
358         } else {
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");
367
368                         if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
369                                 _E("Failed to open waring popup!!");
370                                 return VOLUME_ERROR_FAIL;
371                         }
372                         if (device_display_get_state(&state) != DEVICE_ERROR_NONE)
373                                 _E("Failed to get display state");
374
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");
379                         }
380                         if (status == LOCK_AND_MEDIA)
381                                 /* Check LCD */
382                                 volume_view_window_show(sound_type);
383
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);
391                 }
392         }
393
394         if (sound_type != SOUND_TYPE_ALARM)
395                 volume_sound_play();
396
397         volume_timer_del(TYPE_TIMER_SD);
398         volume_timer_del(TYPE_TIMER_SU);
399         volume_timer_add(0.5, TYPE_TIMER_SD);
400
401         return VOLUME_ERROR_OK;
402 }
403
404 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type)
405 {
406         int is_enabled = 0;
407
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;
413                 }
414                 _D("volume popup enabled in alarm type : %d", is_enabled);
415
416                 if (!is_enabled) {
417                         _D("alarm type but vconf for the volume popup is disabled");
418                         return VOLUME_ERROR_FAIL;
419                 }
420         }
421
422         return VOLUME_ERROR_OK;
423 }
424
425 static Eina_Bool _key_press_cb(void *data, int type, void *event)
426 {
427         int sound = 0;
428         int lock = IDLELOCK_ON;
429         int key_status = 0;
430         int status = 0;
431         int error = 0;
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;
437
438         ev = (Ecore_Event_Key*) event;
439         retv_if(!ev, ECORE_CALLBACK_CANCEL);
440
441         _D("Key Press CB : %s", ev->keyname);
442
443         win = volume_view_win_get();
444         retv_if(!win, ECORE_CALLBACK_CANCEL);
445
446         if (volume_view_warning_popup_get()) {
447                 _D("Safety warning popup is exist");
448                 return ECORE_CALLBACK_CANCEL;
449         }
450
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);
454         }
455
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;
459         }
460
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;
464         }
465
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;
469         }
470         retvm_if(key_status == 2, ECORE_CALLBACK_CANCEL, "starter use volume key. status : 2");
471
472 #ifndef FEATURE_SDK
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;
478         }
479 #endif
480
481         status = volume_control_check_status(&lock, &sound_type);
482         _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
483
484         sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
485         _D("sound status : %d", sound);
486
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);
490
491         earphone_connected = earphone_get_earphone_is_connected();
492         _D("module state - bt: %d, earphone: %d", bt_opened, earphone_connected);
493
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;
497         }
498
499         volume_control_show_view(status, sound_type, sound, bt_opened, earphone_connected);
500
501         key_event_info.is_pressing = EINA_TRUE;
502
503         volume_timer_del(TYPE_TIMER_POPUP);
504
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");
511         }
512
513         return ECORE_CALLBACK_CANCEL;
514 }
515
516 static Eina_Bool _key_release_cb(void *data, int type, void *event)
517 {
518         Ecore_Event_Key *ev = event;
519         retv_if(ev == NULL, ECORE_CALLBACK_CANCEL);
520         _D("Key Release CB : %s", ev->keyname);
521
522         Evas_Object *win = volume_view_win_get();
523         retv_if(win == NULL, ECORE_CALLBACK_CANCEL);
524
525         key_event_info.is_pressing = EINA_FALSE;
526
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;
534         }
535
536         if (!strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
537                 _D("BACK Key is released");
538                 return ECORE_CALLBACK_CANCEL;
539         }
540
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);
547         }
548
549         volume_timer_del(TYPE_TIMER_POPUP);
550
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);
554         }
555
556         _D("key release fini");
557         return ECORE_CALLBACK_CANCEL;
558 }
559