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