Add Tizen-ws-shell
[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
25 #include "main.h"
26 #include "_util_log.h"
27 #include "_util_efl.h"
28 #include "view.h"
29 #include "control.h"
30 #include "sound.h"
31 #include "timer.h"
32 #include "key_event.h"
33 #include "bt.h"
34
35 #define VCONFKEY_ALARM_VOLUME_POPUP_ENABLE  "memory/alarm/volume_popup_enable"
36 #define VOLUME_INPUT_WIN_NAME "volumekey-input-window"
37
38 struct _key_event_s_info {
39         Ecore_X_Window input_win;
40
41         Ecore_Event_Handler *handler_volume_up;
42         Ecore_Event_Handler *handler_volume_down;
43         Ecore_Event_Handler *handler_qp_state_check;
44
45         Eina_Bool is_mute;
46         Eina_Bool is_pressing;
47
48         int count_grabed;
49
50         int last_value_in_media;
51 };
52
53 static struct _key_event_s_info key_event_info = {
54         .input_win = 0,
55
56         .handler_volume_up = NULL,
57         .handler_volume_down = NULL,
58         .handler_qp_state_check = NULL,
59
60         .is_mute = EINA_FALSE,
61         .is_pressing = EINA_FALSE,
62
63         .count_grabed = 0,
64
65         .last_value_in_media = 0,
66 };
67
68 static Eina_Bool _key_release_cb(void *data, int type, void *event);
69 static Eina_Bool _key_press_cb(void *data, int type, void *event);
70 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type);
71 static volume_error_e _volume_down_key_press(sound_type_e sound_type, int sound, bool bt_opened);
72 static volume_error_e _volume_up_key_press(sound_type_e sound_type, int sound, bool bt_opened);
73 static volume_error_e _mute_key_press();
74
75 Ecore_Event_Handler* volume_key_event_handler_volume_up_get(void)
76 {
77         return key_event_info.handler_volume_up;
78 }
79
80 Ecore_Event_Handler* volume_key_event_handler_volume_down_get(void)
81 {
82         return key_event_info.handler_volume_down;
83 }
84
85 Eina_Bool volume_key_event_is_pressing_get(void)
86 {
87         return key_event_info.is_pressing;
88 }
89
90 void volume_key_event_handler_add(void)
91 {
92         if(!key_event_info.handler_volume_up)
93                 key_event_info.handler_volume_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL);
94
95         if(!key_event_info.handler_volume_down)
96                 key_event_info.handler_volume_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL);
97 }
98
99 void volume_key_event_handler_del(void)
100 {
101         ret_if(key_event_info.handler_volume_up == NULL);
102         ecore_event_handler_del(key_event_info.handler_volume_up);
103         key_event_info.handler_volume_up= NULL;
104
105         ret_if(key_event_info.handler_volume_down == NULL);
106         ecore_event_handler_del(key_event_info.handler_volume_down);
107         key_event_info.handler_volume_down = NULL;
108 }
109
110 static volume_error_e _mute_key_press()
111 {
112         int lastval = -1;
113         int lock = IDLELOCK_ON;
114         int status = 0;
115         int sound = 0;
116         int error = 0;
117         bool bt_opened = false;
118         sound_type_e sound_type = 0;
119
120         status = volume_control_check_status(&lock, &sound_type);
121         _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
122
123         sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
124         _D("sound status : %d", sound);
125
126         error = bt_ag_is_sco_opened(&bt_opened);
127         if(error != BT_ERROR_NONE)
128                 _E("bt_ag_is_sco_opened return [%d]", error);
129
130         _D("BT state %d", bt_opened);
131
132         volume_control_show_view(status, sound_type, sound, bt_opened);
133
134         if (sound_type == SOUND_TYPE_MEDIA) {
135                 if (key_event_info.is_mute == EINA_FALSE) {
136                         _D("media is playing. set media volume to 0.");
137                         lastval = volume_sound_level_get(sound_type);
138                         retv_if(lastval == -1, VOLUME_ERROR_FAIL);
139
140                         key_event_info.last_value_in_media = lastval;
141                         volume_sound_level_set(sound_type, 0);
142                         if (VOLUME_ERROR_OK != volume_view_slider_value_set(0)) {
143                                 _E("Failed to set slider value");
144                                 return VOLUME_ERROR_FAIL;
145                         }
146                         key_event_info.is_mute = EINA_TRUE;
147                         return VOLUME_ERROR_OK;
148                 } else {
149                         _D("toggle the mute key to normal in media. last value in media : %d", key_event_info.last_value_in_media);
150                         volume_sound_level_set(sound_type, lastval);
151                         if (VOLUME_ERROR_OK != volume_view_slider_value_set(lastval)) {
152                                 _E("Failed to set slider value");
153                                 return VOLUME_ERROR_FAIL;
154                         }
155                         key_event_info.is_mute = EINA_FALSE;
156                         return VOLUME_ERROR_OK;
157                 }
158         } else {
159                 if (lock == IDLELOCK_ON) {
160                         _D("lock is on, block the MUTE key");
161                         return VOLUME_ERROR_OK;
162                 }
163
164                 if (volume_mute_toggle_set())
165                         volume_sound_feedback_play(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_GENERAL);
166
167                 return VOLUME_ERROR_OK;
168         }
169 }
170
171 static volume_error_e _volume_up_key_press(sound_type_e sound_type, int sound, bool bt_opened)
172 {
173         int sound_step = 0;
174         int sound_level = 0;
175         int vibration = 0;
176
177         _D("Volume Up Key Pressed");
178         key_event_info.is_mute = EINA_FALSE;
179
180         sound_step = volume_sound_step_get();
181         _D("sound step : %d", sound_step);
182
183         sound_level = volume_sound_level_get(sound_type);
184         retv_if(sound_level == -1, VOLUME_ERROR_FAIL);
185         _D("sound level : %d", sound_level);
186
187         vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
188         _D("vibration : %d", vibration);
189
190         if (elm_object_disabled_get(volume_view_slider_get()))
191                 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
192
193         if (sound_type == SOUND_TYPE_RINGTONE) {
194                 if (!sound) {
195                         /* Check sound status change case. */
196                         if (!vibration) {
197                                 _D("mute -> vib.");
198                                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
199                                 volume_sound_vib_play();
200                         }
201                         else {
202                                 _D("vib -> sound");
203                                 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
204                                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
205                                 volume_sound_level_set(sound_type, sound_level+1);
206                                 volume_view_slider_value_set(sound_level+1);
207                                 _D("new sound value: %d", sound_level+1);
208                         }
209                 }
210                 else {
211                         /*adjust the sound level normally */
212                         if (sound_level != sound_step) {
213                                 volume_sound_level_set(sound_type, sound_level+1);
214                                 volume_view_slider_value_set(sound_level+1);
215                                 _D("new sound value: %d", sound_level+1);
216                         }
217                 }
218         }
219         else if (sound_type == SOUND_TYPE_NOTIFICATION) {
220                 if (!sound) {
221                         /* No sound in notification type. */
222                         volume_view_slider_value_set(0);
223                         elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
224                 }
225                 else {
226                         /*adjust the sound level normally */
227                         if (sound_level != sound_step) {
228                                 volume_sound_level_set(sound_type, sound_level+1);
229                                 volume_view_slider_value_set(sound_level+1);
230                                 _D("new sound value: %d", sound_level+1);
231                         }
232                 }
233         }
234         /* Sound type is not ringtone. Need to adjust sound level */
235         else if (sound_type == SOUND_TYPE_CALL && bt_opened) {
236                 int bt_vol = 0;
237                 if (bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
238                         _E("Getting bt volume is failed");
239
240                 _D("BT VOLUME : %d", bt_vol);
241
242                 if (bt_vol != sound_step) {
243                         if(bt_ag_notify_speaker_gain(bt_vol+1) != BT_ERROR_NONE)
244                                 _E("Setting bt volume is failed");
245                         volume_view_slider_value_set(bt_vol+1);
246                         _D("New BT VOLUME : %d", bt_vol+1);
247                 }
248         }
249         else {
250                 if (sound_level != sound_step) {
251                         volume_sound_level_set(sound_type, sound_level+1);
252                         volume_view_slider_value_set(sound_level+1);
253                         _D("new sound value: %d", sound_level+1);
254                 }
255         }
256
257         if (sound_type != SOUND_TYPE_ALARM)
258                 volume_sound_play();
259
260         volume_timer_del(TYPE_TIMER_SU);
261         volume_timer_del(TYPE_TIMER_SD);
262         volume_timer_add(0.5, TYPE_TIMER_SU);
263
264         if (!volume_timer_su_timer_get()) {
265                 _E("Failed to get SUTIMER");
266                 return VOLUME_ERROR_FAIL;
267         }
268
269         return VOLUME_ERROR_OK;
270 }
271
272 static volume_error_e _volume_down_key_press(sound_type_e sound_type, int sound, bool bt_opened)
273 {
274         key_event_info.is_mute = EINA_FALSE;
275
276         int val = volume_sound_level_get(sound_type);
277         retv_if(val == -1, VOLUME_ERROR_FAIL);
278
279         int sound_st = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
280         _D("sound status : %d", sound_st);
281
282         int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
283         _D("vibration : %d", vibration);
284
285         if (elm_object_disabled_get(volume_view_slider_get()))
286                 elm_object_disabled_set(volume_view_slider_get(), EINA_FALSE);
287
288         if(sound_type == SOUND_TYPE_RINGTONE){
289                 if (!sound)
290                         /* Check sound status change case. */
291                         _D("Do nothing.");
292                 else {
293                         if (val != 0) {
294                                 volume_sound_level_set(sound_type, val - 1);
295                                 volume_view_slider_value_set(val - 1);
296                                 /*adjust the sound level normally */
297                                 if (val == 1) {
298                                         volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
299                                         volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
300                                         volume_sound_vib_play();
301                                 }
302                         }
303                 }
304         }
305         else if (sound_type == SOUND_TYPE_NOTIFICATION) {
306                 if(!sound) {
307                         /* No sound in notification type. */
308                         volume_view_slider_value_set(0);
309                         elm_object_disabled_set(volume_view_slider_get(), EINA_TRUE);
310                 }
311                 else {
312                         /*adjust the sound level normally */
313                         if (val != 0) {
314                                 volume_sound_level_set(sound_type, val-1);
315                                 volume_view_slider_value_set(val-1);
316                                 _D("new sound value: %d", val-1);
317                         }
318                 }
319         }
320         else if(sound_type == SOUND_TYPE_CALL && bt_opened) {
321                 int bt_vol = 0;
322                 if(bt_ag_get_speaker_gain(&bt_vol) != BT_ERROR_NONE)
323                         _E("Getting bt volume is failed");
324
325                 _D("BT VOLUME : %d", bt_vol);
326                 if(bt_ag_notify_speaker_gain(bt_vol-1) != BT_ERROR_NONE)
327                         _E("Setting bt volume is failed");
328                 volume_view_slider_value_set(bt_vol-1);
329
330                 _D("New BT VOLUME : %d", bt_vol-1);
331         }
332         /* Sound type is not ringtone. Need to adjust sound level */
333         else {
334                 if (val != 0) {
335                         volume_sound_level_set(sound_type, val - 1);
336                         volume_view_slider_value_set(val - 1);
337                         _D("new sound value: %d", val-1);
338                 }
339         }
340
341         if(sound_type != SOUND_TYPE_ALARM)
342                 volume_sound_play();
343
344         volume_timer_del(TYPE_TIMER_SD);
345         volume_timer_del(TYPE_TIMER_SU);
346         volume_timer_add(0.5, TYPE_TIMER_SD);
347
348         return VOLUME_ERROR_OK;
349 }
350
351 static volume_error_e _volume_popup_check_in_alarm_type(sound_type_e sound_type)
352 {
353         int is_enabled = 0;
354
355         if(sound_type == SOUND_TYPE_ALARM) {
356                 _D("Sound type is Alarm Type");
357                 if(vconf_get_bool(VCONFKEY_ALARM_VOLUME_POPUP_ENABLE, &is_enabled) < 0) {
358                         _E("Failed to get vconfkey : VCONFKEY_ALARM_VOLUME_POPUP_ENABLE");
359                         return VOLUME_ERROR_FAIL;
360                 }
361                 _D("volume popup enabled in alarm type : %d", is_enabled);
362
363                 if(!is_enabled) {
364                         _D("alarm type but vconf for the volume popup is disabled");
365                         return VOLUME_ERROR_FAIL;
366                 }
367         }
368
369         return VOLUME_ERROR_OK;
370 }
371
372 static Eina_Bool _key_press_cb(void *data, int type, void *event)
373 {
374         int sound = 0;
375         int lock = IDLELOCK_ON;
376         int key_status = 0;
377         int status = 0;
378         int error = 0;
379         bool bt_opened = false;
380         sound_type_e sound_type = 0;
381         Evas_Object *win = NULL;
382         Ecore_Event_Key *ev = NULL;
383
384         ev = (Ecore_Event_Key*) event;
385         retv_if(!ev, ECORE_CALLBACK_CANCEL);
386
387         _D("Key Press CB : %s", ev->keyname);
388
389         win = volume_view_win_get();
390         retv_if(!win, ECORE_CALLBACK_CANCEL);
391
392         if(!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL)) || !strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
393                 _D("%s is pressed", ev->keyname);
394                 return ECORE_CALLBACK_CANCEL;
395         }
396
397         if(volume_view_is_slider_touching_get()) {
398                 _E("Failed to show volume : is_slider_touching is EINA_TRUE");
399                 return ECORE_CALLBACK_CANCEL;
400         }
401
402         if(vconf_get_int(VCONFKEY_STARTER_USE_VOLUME_KEY, &key_status) < 0) {
403                 _E("Failed to get vconf : VCONFKEY_STATER_USE_VOLUME_KEY");
404                 return ECORE_CALLBACK_CANCEL;
405         }
406         retvm_if(key_status == 2, ECORE_CALLBACK_CANCEL, "starter use volume key. status : 2");
407
408 #ifndef FEATURE_SDK
409         int is_call = -1;
410         if(!strncmp(ev->keyname, KEY_MUTE, strlen(KEY_MUTE))) {
411                 _D("MUTE key is pressed");
412                 if(VOLUME_ERROR_OK != _mute_key_press())
413                         _E("Failed to press MUTE key");
414                 return ECORE_CALLBACK_CANCEL;
415         }
416
417         if(vconf_get_int(VCONFKEY_TELEPHONY_CALL_STATE, &is_call) < 0 || is_call < 0) {
418                 _E("Failed to get call state vconf");
419                 return ECORE_CALLBACK_CANCEL;
420         }
421         if(is_call>0) {
422                 _D("Call is active");
423                 return ECORE_CALLBACK_CANCEL;
424         }
425 #endif
426
427         status = volume_control_check_status(&lock, &sound_type);
428         _D("status: %d, lock: %d, sound type : %d", status, lock, sound_type);
429
430         sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
431         _D("sound status : %d", sound);
432
433         error = bt_ag_is_sco_opened(&bt_opened);
434         if(error != BT_ERROR_NONE)
435                 _E("bt_ag_is_sco_opened return [%d]", error);
436
437         _D("BT state %d", bt_opened);
438
439         if(VOLUME_ERROR_OK != _volume_popup_check_in_alarm_type(sound_type)) {
440                 _E("Failed to set volume popup");
441                 return ECORE_CALLBACK_CANCEL;
442         }
443
444         volume_control_show_view(status, sound_type, sound, bt_opened);
445
446         key_event_info.is_pressing = EINA_TRUE;
447
448         volume_timer_del(TYPE_TIMER_POPUP);
449
450         if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
451                 if(VOLUME_ERROR_OK != _volume_up_key_press(sound_type, sound, bt_opened))
452                         _E("Failed to press volume up key");
453         }
454         else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
455                 if(VOLUME_ERROR_OK != _volume_down_key_press(sound_type, sound, bt_opened))
456                         _E("Failed to press volume down key");
457         }
458
459         return ECORE_CALLBACK_CANCEL;
460 }
461
462 static Eina_Bool _key_release_cb(void *data, int type, void *event)
463 {
464         Ecore_Event_Key *ev = event;
465         retv_if(ev == NULL, ECORE_CALLBACK_CANCEL);
466         _D("Key Release CB : %s", ev->keyname);
467
468         Evas_Object *win = volume_view_win_get();
469         retv_if(win == NULL, ECORE_CALLBACK_CANCEL);
470
471         key_event_info.is_pressing = EINA_FALSE;
472
473         if(!strncmp(ev->keyname, KEY_CANCEL, strlen(KEY_CANCEL))) {
474                 _D("%s is released", ev->keyname);
475                 if(VOLUME_ERROR_OK != volume_control_hide_view())
476                         _E("Failed to close volume");
477                 if(VOLUME_ERROR_OK != volume_control_cache_flush())
478                         _E("Failed to flush cache");
479                 return ECORE_CALLBACK_CANCEL;
480         }
481
482         if(!strncmp(ev->keyname, KEY_BACK, strlen(KEY_BACK))) {
483                 _D("BACK Key is released");
484                 return ECORE_CALLBACK_CANCEL;
485         }
486
487         if (!strncmp(ev->keyname, KEY_VOLUMEUP, strlen(KEY_VOLUMEUP))) {
488                 _D("up key released and del timer");
489                 volume_timer_del(TYPE_TIMER_SU);
490         }
491         else if (!strncmp(ev->keyname, KEY_VOLUMEDOWN, strlen(KEY_VOLUMEDOWN))) {
492                 _D("down key released and del timer");
493                 volume_timer_del(TYPE_TIMER_SD);
494         }
495
496         volume_timer_del(TYPE_TIMER_POPUP);
497
498         if(volume_view_is_slider_touching_get() == EINA_FALSE)
499                 volume_timer_add(3.0, TYPE_TIMER_POPUP);
500
501         _D("key release fini");
502         return ECORE_CALLBACK_CANCEL;
503 }
504