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