Merge branch 'tizen' into tizen_3.0
[apps/native/volume-app.git] / src / timer.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 <vconf.h>
18 #include <vconf-keys.h>
19 #include <bluetooth.h>
20 #include <bluetooth_internal.h>
21 #include <bluetooth_extension.h>
22 #include <vconf-keys.h>
23 #include <device/display.h>
24 #include <feedback.h>
25
26 #include "main.h"
27 #include "_util_log.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 #include "earphone.h"
35
36 #define DEL_TIMER(x) \
37         if (x) {\
38                 _D("DELTIMER x : %p\n", x);\
39                 ecore_timer_del(x);\
40                 x = NULL;\
41         }
42 #define ADD_TIMER(x, time, _timer_cb, data) \
43         if(x != NULL) DEL_TIMER(x); \
44         x = ecore_timer_add(time, _timer_cb, data);\
45         _D("ADDTIMER x : %p\n", x);\
46
47
48 struct _timer_s_info {
49         Ecore_Timer *popup_timer; /* pop-up timer */
50         Ecore_Timer *slider_timer; /* slider timer */
51         Ecore_Timer *su_timer; /* short up timer */
52         Ecore_Timer *sd_timer; /* short down timer */
53         Ecore_Timer *lu_timer; /* long up timer */
54         Ecore_Timer *ld_timer; /* long down timer */
55         Ecore_Timer *bt_timer; /* long down timer */
56         Ecore_Timer *warning_popup_timer; /* long down timer */
57 };
58
59 static struct _timer_s_info timer_info = {
60         .popup_timer = NULL,
61         .slider_timer = NULL,
62         .su_timer = NULL,
63         .sd_timer = NULL,
64         .lu_timer = NULL,
65         .ld_timer = NULL,
66         .bt_timer = NULL,
67         .warning_popup_timer = NULL,
68 };
69
70 static Eina_Bool _timer_short_down_cb(void *data);
71 static Eina_Bool _timer_short_up_cb(void *data);
72 static Eina_Bool _timer_slider_cb(void *data);
73 static Eina_Bool _timer_popup_cb(void *data);
74 static Eina_Bool _timer_bt_cb(void *data);
75 static Eina_Bool _timer_warning_popup_cb(void *data);
76
77 Ecore_Timer *volume_timer_bt_timer_get(void)
78 {
79         return timer_info.bt_timer;
80 }
81
82 Ecore_Timer *volume_timer_popup_timer_get(void)
83 {
84         return timer_info.popup_timer;
85 }
86
87 Ecore_Timer *volume_timer_slider_timer_get(void)
88 {
89         return timer_info.slider_timer;
90 }
91
92 Ecore_Timer *volume_timer_su_timer_get(void)
93 {
94         return timer_info.su_timer;
95 }
96
97 Ecore_Timer *volume_timer_sd_timer_get(void)
98 {
99         return timer_info.sd_timer;
100 }
101
102 void volume_timer_add(double time, volume_timer_type type)
103 {
104         _D("VOLUME TIMER ADD: %d", type);
105         if (type == TYPE_TIMER_POPUP) {
106                 ADD_TIMER(timer_info.popup_timer, time, _timer_popup_cb, NULL);
107         } else if (type == TYPE_TIMER_SLIDER) {
108                 ADD_TIMER(timer_info.slider_timer, time, _timer_slider_cb, NULL);
109         } else if (type == TYPE_TIMER_SD) {
110                 ADD_TIMER(timer_info.sd_timer, time, _timer_short_down_cb, NULL);
111         } else if (type == TYPE_TIMER_SU) {
112                 ADD_TIMER(timer_info.su_timer, time, _timer_short_up_cb, NULL);
113         } else if (type == TYPE_TIMER_BT) {
114                 ADD_TIMER(timer_info.bt_timer, time, _timer_bt_cb, NULL);
115         } else if (type == TYPE_TIMER_WARNING_POPUP) {
116                 ADD_TIMER(timer_info.warning_popup_timer, time, _timer_warning_popup_cb, NULL);
117         } else {
118                 _E("Failed to get type : type error(%d)", type);
119                 return;
120         }
121 }
122
123 void volume_timer_del(volume_timer_type type)
124 {
125         _D("volume timer del: %d", type);
126         if (type == TYPE_TIMER_POPUP) {
127                 DEL_TIMER(timer_info.popup_timer);
128         } else if (type == TYPE_TIMER_SLIDER) {
129                 DEL_TIMER(timer_info.slider_timer);
130         } else if (type == TYPE_TIMER_SD) {
131                 DEL_TIMER(timer_info.sd_timer);
132         } else if (type == TYPE_TIMER_SU) {
133                 DEL_TIMER(timer_info.su_timer);
134         } else if (type == TYPE_TIMER_BT) {
135                 DEL_TIMER(timer_info.bt_timer);
136         } else if (type == TYPE_TIMER_WARNING_POPUP) {
137                 DEL_TIMER(timer_info.warning_popup_timer);
138         } else {
139                 _E("Failed to get type : type error(%d)", type);
140                 return;
141         }
142 }
143
144 static Eina_Bool _timer_bt_cb(void *data)
145 {
146         if (VOLUME_ERROR_OK != volume_control_close_bt_display())
147                 _E("Failed to close volume");
148         if (VOLUME_ERROR_OK != volume_control_cache_flush())
149                 _E("Failed to flush cache");
150
151         return ECORE_CALLBACK_CANCEL;
152 }
153
154 static Eina_Bool _timer_popup_cb(void *data)
155 {
156         if (VOLUME_ERROR_OK != volume_control_hide_view())
157                 _E("Failed to close volume");
158         if (VOLUME_ERROR_OK != volume_control_cache_flush())
159                 _E("Failed to flush cache");
160
161         return ECORE_CALLBACK_CANCEL;
162 }
163
164 static Eina_Bool _timer_warning_popup_cb(void *data)
165 {
166         volume_view_destroy_warning_popup();
167
168         if (VOLUME_ERROR_OK != volume_control_hide_view())
169                 _E("Failed to close volume");
170         if (VOLUME_ERROR_OK != volume_control_cache_flush())
171                 _E("Failed to flush cache");
172
173         return ECORE_CALLBACK_CANCEL;
174 }
175
176 static Eina_Bool _timer_slider_cb(void *data)
177 {
178         Evas_Object *slider = volume_view_slider_get();
179         if (slider == NULL) {
180                 timer_info.slider_timer = NULL;
181                 return ECORE_CALLBACK_CANCEL;
182         }
183
184         double val = 0;
185
186         int sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
187         _D("sound status : %d", sound);
188
189 #if 0
190         int vibration = volume_sound_vconf_status_get(TYPE_VCONF_VIBRATION_STATUS);
191         _D("vibration : %d", vibration);
192 #endif
193
194         sound_type_e sound_type = volume_control_get_sound_type_at_show();
195         _D("sound type at show : %d", sound_type);
196
197         val = elm_slider_value_get(slider);
198         val += 0.5;
199         _D("slider value : %d", (int)val);
200
201         if ((int)val != 0) {
202                 if (sound_type != SOUND_TYPE_MEDIA) {
203                         volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
204                         volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
205                 }
206                 volume_sound_is_vibration_set(EINA_FALSE);
207         }
208         if (val < 1) {
209                 if (sound_type != SOUND_TYPE_MEDIA) {
210                         volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
211
212                         if (sound) {
213                                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
214                                 volume_sound_vib_play();
215                         }
216                 }
217                 elm_slider_value_set(slider, 0);
218                 volume_sound_level_set(sound_type, 1);
219         }
220
221         return ECORE_CALLBACK_RENEW;
222 }
223
224 static Eina_Bool _timer_short_up_cb(void *data)
225 {
226         _D("volume is in LongPress");
227         bool bt_opened = false;
228         int error = 0;
229         int earphone_connected = 0;
230
231         Evas_Object *win = volume_view_win_get();
232         if (!win) {
233                 _E("Window is NULL");
234                 return ECORE_CALLBACK_CANCEL;
235         }
236
237         sound_type_e sound_type = volume_control_get_sound_type_at_show();
238         _D("sound type at show : %d", sound_type);
239
240         if (!evas_object_visible_get(win) && sound_type == SOUND_TYPE_RINGTONE) {
241                 _E("Window is hidden");
242                 return ECORE_CALLBACK_CANCEL;
243         }
244
245         if (volume_view_is_slider_touching_get())
246                 return ECORE_CALLBACK_RENEW;
247
248         ecore_timer_interval_set(timer_info.su_timer, 0.1);
249         volume_timer_del(TYPE_TIMER_SLIDER);
250
251         int sound_step = volume_sound_step_get();
252         _D("sound step : %d", sound_step);
253
254         int sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
255         _D("sound status : %d", sound);
256
257         int val = volume_sound_level_get(sound_type);
258         if (val == -1) {
259                 _E("Failed to get volume level");
260                 return ECORE_CALLBACK_CANCEL;
261         }
262         _D("sound value : %d", val);
263
264         error = bt_ag_is_sco_opened(&bt_opened);
265         if(error != BT_ERROR_NONE) {
266                 _E("bt_ag_is_sco_opened return [%d]", error);
267         }
268         earphone_connected = earphone_get_earphone_is_connected();
269         _D("module state - bt: %d, earphone: %d", bt_opened, earphone_connected);
270
271         if (sound_type == SOUND_TYPE_MEDIA && (bt_opened || earphone_connected) && val + 1 > SAFETY_LIMIT) {
272                 if (volume_control_get_safety_limit()) {
273                         sound_type_e type = 0;
274                         display_state_e state;
275                         int lock = IDLELOCK_ON;
276                         int status = volume_control_check_status(&lock, &type);
277                         volume_sound_level_set(sound_type, SAFETY_LIMIT);
278                         volume_view_slider_value_set(SAFETY_LIMIT);
279                         if (VOLUME_ERROR_OK != volume_view_send_warning_signal(EINA_TRUE)) {
280                                 _E("Failed to set warning status");
281                         }
282                         if (VOLUME_ERROR_OK != volume_view_open_warning_popup()) {
283                                 _E("Failed to open waring popup!!");
284                                 return VOLUME_ERROR_FAIL;
285                         }
286                         if (device_display_get_state(&state) != DEVICE_ERROR_NONE) {
287                                 _E("Failed to get display state");
288                         }
289                         if (state == DISPLAY_STATE_SCREEN_OFF || state == DISPLAY_STATE_SCREEN_DIM) {
290                                 device_display_change_state(DISPLAY_STATE_NORMAL);
291                                 if(FEEDBACK_ERROR_NONE != feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_WAKEUP)) {
292                                         _E("Failed to play vibration");
293                                 }
294                         }
295                         if (status == LOCK_AND_MEDIA) {
296                                 /* Check LCD */
297                                 volume_view_window_show(sound_type);
298                         }
299                         volume_timer_del(TYPE_TIMER_SU);
300                         volume_timer_del(TYPE_TIMER_SD);
301                         volume_timer_add(10.0, TYPE_TIMER_WARNING_POPUP);
302                         return VOLUME_ERROR_OK;
303                 }
304         }
305
306         if (val == sound_step) {
307                 _D("already sound value : %d", sound_step);
308                 return ECORE_CALLBACK_RENEW;
309         }
310
311         if (!sound && sound_type == SOUND_TYPE_NOTIFICATION) {
312                 _D("Do not adjust the noti type in no sound.");
313                 return ECORE_CALLBACK_RENEW;
314         }
315
316         if (!sound && sound_type == SOUND_TYPE_RINGTONE) {
317                 volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 1);
318                 volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 0);
319         }
320
321         if (volume_sound_level_set(sound_type, val+1 > sound_step ? sound_step : val+1)) {
322                 _D("[SAFETY_SOUND] release timer");
323                 volume_timer_add(3.0, TYPE_TIMER_POPUP);
324         }
325         val = volume_sound_level_get(sound_type);
326
327         return ECORE_CALLBACK_RENEW;
328 }
329
330 static Eina_Bool _timer_short_down_cb(void *data)
331 {
332         Evas_Object *win = volume_view_win_get();
333         if (!win) {
334                 _E("Window is NULL");
335                 return ECORE_CALLBACK_CANCEL;
336         }
337
338         sound_type_e sound_type = volume_control_get_sound_type_at_show();
339         _D("sound type at show : %d", sound_type);
340
341         if (!evas_object_visible_get(win) && sound_type == SOUND_TYPE_RINGTONE) {
342                 _E("Window is hidden");;
343                 return ECORE_CALLBACK_CANCEL;
344         }
345
346         if (volume_view_is_slider_touching_get())
347                 return ECORE_CALLBACK_RENEW;
348
349         ecore_timer_interval_set(timer_info.sd_timer, 0.1);
350         volume_timer_del(TYPE_TIMER_SLIDER);
351
352         int sound = volume_sound_vconf_status_get(TYPE_VCONF_SOUND_STATUS);
353         _D("sound status : %d", sound);
354
355         int val = volume_sound_level_get(sound_type);
356         if (val == -1) {
357                 _E("Failed to get volume level");
358                 return ECORE_CALLBACK_CANCEL;
359         }
360
361         if (!sound && sound_type == SOUND_TYPE_NOTIFICATION) {
362                 _D("Do not adjust the noti type in no sound.");
363                 return ECORE_CALLBACK_RENEW;
364         }
365         _D("sound value : %d", val);
366
367         if (val == 1) {
368                 if (sound && sound_type == SOUND_TYPE_RINGTONE) {
369                         _D("Set sound status to vibration in long press");
370                         volume_sound_vconf_status_set(TYPE_VCONF_SOUND_STATUS, 0);
371                         volume_sound_vconf_status_set(TYPE_VCONF_VIBRATION_STATUS, 1);
372                         volume_sound_vib_play();
373                 }
374         } else if (!val) {
375                 _D("already sound value : 0");
376                 return ECORE_CALLBACK_RENEW;
377         }
378
379         if (sound || sound_type != SOUND_TYPE_RINGTONE)
380                 volume_sound_level_set(sound_type, val-1 <= 0 ? 0 : val-1);
381
382         return ECORE_CALLBACK_RENEW;
383 }
384