76d4344d211ce64fe6119d7595623ed7f36fcce2
[apps/home/call.git] / call-engine / voice-call-device.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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
18 #include "voice-call-device.h"
19 #include "voice-call-dbus.h"
20 #include "voice-call-core.h"
21 #include "voice-call-sound.h"
22 #include "voice-call-bt.h"
23 #include "voice-call-core.h"
24 #include "voice-call-engine-msg.h"
25
26 #include "vc-core-callagent.h"
27 #include "vc-core-engine-types.h"
28 #include "vc-core-util.h"
29
30 #include <pmapi.h>
31 #include <sensor.h>
32
33 static int g_proximity_sensor_handle = -1;
34 static int g_proximity_sensor_state = -1;
35
36 static gboolean __voicecall_dvc_proximity_sensor_is_request(unsigned int type, sensor_event_data_t *event, void *data);
37 static void __voicecall_dvc_proximity_sensor_callback_func(unsigned int type, sensor_event_data_t *event, void *data);
38 static gboolean __voicecall_dvc_earjack_status_cb(keynode_t *node, call_vc_core_state_t *pcall_core);
39 static gboolean __voicecall_dvc_earjackkey_status_cb(keynode_t *node, call_vc_core_state_t *pcall_core);
40
41 /**
42  * This function handles earjack event
43  *
44  * @return              Returns TRUE on success or FALSE on failure
45  * @param[in]           node                            vconf node      
46  * @param[in]           pcall_core                      Handle to voicecall core                
47  */
48 static gboolean __voicecall_dvc_earjack_status_cb(keynode_t *node, call_vc_core_state_t *pcall_core)
49 {
50         gboolean bRecieverPath = FALSE;
51         int earjack_status;
52
53         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
54
55         earjack_status = vconf_keynode_get_int(node);
56
57         CALL_ENG_DEBUG(ENG_DEBUG, "Earjack Status: %d \n", earjack_status);
58
59         vc_engine_headset_status_type event_data;
60
61         /*Change path only if outgoing call or connected call exists */
62 #ifdef _NEW_SND_
63         if ((TRUE == voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine)) 
64         || (TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine))) {
65                 if (earjack_status == TRUE) {
66                         voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_EARJACK);
67                         voicecall_snd_change_path(pcall_core->papp_snd);
68                         memset(&event_data, 0, sizeof(event_data));
69                         event_data.bstatus = earjack_status;
70                         vcall_engine_send_event_to_client(VC_ENGINE_MSG_EARJACK_STATUS_TO_UI, (void *)&event_data);                     
71                 } else {
72                         if (voicecall_snd_get_path_status(pcall_core->papp_snd) == VOICE_CALL_SND_PATH_EARJACK) {
73                                 if (_vc_bt_is_bt_connected(pcall_core) == TRUE) {
74                                         voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_BT);                            
75                                         /*_vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_SWITCH_TO_HEADSET, -1, NULL);*/
76                                         _vc_bt_request_switch_headset_path(pcall_core, TRUE);
77                                 } else {
78                                         voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_RECEIVER);                              
79                                         voicecall_snd_change_path(pcall_core->papp_snd);
80                                 }
81                                 memset(&event_data, 0, sizeof(event_data));
82                                 event_data.bstatus = earjack_status;
83                                 vcall_engine_send_event_to_client(VC_ENGINE_MSG_EARJACK_STATUS_TO_UI, (void *)&event_data);                             
84                         } else {
85                                 CALL_ENG_DEBUG(ENG_DEBUG, "No path change");
86                         }
87                 }
88         }
89 #else
90         if ((TRUE == voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine)) || (TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine))) {
91                 memset(&event_data, 0, sizeof(event_data));
92                 event_data.bstatus = earjack_status;
93                 vcall_engine_send_event_to_client(VC_ENGINE_MSG_EARJACK_STATUS_TO_UI, (void *)&event_data);
94         }
95 #endif
96         return TRUE;
97 }
98
99 /**
100  * This function handles earjack key event
101  *
102  * @return              Returns TRUE on success or FALSE on failure
103  * @param[in]           node                            vconf node      
104  * @param[in]           pcall_core                      Handle to voicecall core                
105  */
106 static gboolean __voicecall_dvc_earjackkey_status_cb(keynode_t *node, call_vc_core_state_t *pcall_core)
107 {
108         int key_value;
109
110         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
111
112         key_value = vconf_keynode_get_int(node);
113
114         CALL_ENG_DEBUG(ENG_DEBUG, "key_value: %d \n", key_value);
115
116         if (key_value > 0) {
117                 if (voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) {
118                         voicecall_core_end_all_calls(pcall_core);
119                 } else if (voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine)) {
120 #ifdef _NEW_SND_
121                         voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_EARJACK);
122 #endif
123                         voicecall_core_answer_call(pcall_core, FALSE);
124                 } else if (voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine)) {
125                         voicecall_core_cancel_call(pcall_core);
126                 }
127         }
128
129         return TRUE;
130 }
131
132 /**
133  * This function initialize earjack event.
134  *
135  * @return              Returns TRUE on success or FALSE on failure
136  * @param[in]           pcall_core                      Handle to voicecall core                
137  */
138 gboolean _voicecall_dvc_earjack_init(call_vc_core_state_t *pcall_core)
139 {
140 #ifdef _NEW_SND_
141 #else
142         int earjack_status = -1;
143         if (!vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status)) {
144                 CALL_ENG_DEBUG(ENG_DEBUG, "earjack_status:[%d]\n", earjack_status);
145                 if (earjack_status == VCONFKEY_SYSMAN_EARJACK_REMOVED) {
146                         voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_EARJACK, FALSE);
147                         CALL_ENG_DEBUG(ENG_DEBUG, "*****************VOICE_CALL_AUDIO_EARJACK = FALSE **********\n");
148                 } else {
149                         voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_EARJACK, TRUE);
150                         CALL_ENG_DEBUG(ENG_DEBUG, "*****************VOICE_CALL_AUDIO_EARJACK = TRUE **********\n");
151                 }
152         } else {
153                 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_int failed..\n");
154                 voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_EARJACK, FALSE);
155         }
156 #endif
157
158         vconf_notify_key_changed(VCONFKEY_SYSMAN_EARJACK, (void *)__voicecall_dvc_earjack_status_cb, pcall_core);
159         vconf_notify_key_changed(VCONFKEY_SYSMAN_EARJACKKEY, (void *)__voicecall_dvc_earjackkey_status_cb, pcall_core);
160         return TRUE;
161 }
162
163 void _voicecall_dvc_get_earjack_status(call_vc_core_state_t *pcall_core)
164 {
165         int earjack_status = -1;
166         if (!vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status)) {
167                 CALL_ENG_DEBUG(ENG_DEBUG, "earjack_status:[%d]\n", earjack_status);
168                 if (earjack_status == VCONFKEY_SYSMAN_EARJACK_REMOVED) {
169                         voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_EARJACK, FALSE);
170                         CALL_ENG_DEBUG(ENG_DEBUG, "*****************VOICE_CALL_AUDIO_EARJACK = FALSE **********\n");
171                 } else {
172                         voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_EARJACK, TRUE);
173                         CALL_ENG_DEBUG(ENG_DEBUG, "*****************VOICE_CALL_AUDIO_EARJACK = TRUE **********\n");
174                 }
175         } else {
176                 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_int failed..\n");
177                 voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_EARJACK, FALSE);
178         }
179 }
180
181 gboolean _voicecall_dvc_get_earjack_connected()
182 {
183         int earjack_status = -1;
184         if (!vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status)) {
185                 CALL_ENG_DEBUG(ENG_DEBUG, "earjack_status:[%d]\n", earjack_status);
186                 if (earjack_status == VCONFKEY_SYSMAN_EARJACK_REMOVED) {
187                         return FALSE;
188                 } else {
189                         return TRUE;
190                 }
191         } else {
192                 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_int failed..\n");
193                 return FALSE;
194         }
195 }
196
197 void _voicecall_dvc_control_lcd_state(voicecall_lcd_control_t state)
198 {
199         CALL_ENG_DEBUG(ENG_DEBUG,"[%d]", state);
200         switch (state) {
201         case VC_LCD_OFF:
202                 pm_change_state(LCD_OFF);
203                 break;
204
205         case VC_LCD_ON:
206                 pm_change_state(LCD_NORMAL);
207                 break;
208
209         case VC_LCD_ON_LOCK:
210                 pm_lock_state(LCD_NORMAL, GOTO_STATE_NOW, 0);
211                 break;
212
213         case VC_LCD_ON_UNLOCK:
214                 pm_unlock_state(LCD_NORMAL, PM_RESET_TIMER);
215                 break;
216
217         default:
218                 break;
219         }
220 }
221  
222 gboolean _voicecall_dvc_proximity_sensor_init(void *data)
223 {
224         CALL_ENG_DEBUG(ENG_DEBUG, "..");
225         int ret = -1;
226         int handle = -1;
227 #ifdef _POLLING_PROXIMITY_SENSOR_
228         event_condition_t my_cond;
229 #endif
230         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)data;
231         sensor_data_t cur_sensor_data;
232
233         if (g_proximity_sensor_handle >= 0) {
234                 CALL_ENG_DEBUG(ENG_WARN, "already initialized");
235                 return FALSE;
236         }
237
238         handle = sf_connect(PROXIMITY_SENSOR);
239         if (handle < 0) {
240                 CALL_ENG_DEBUG(ENG_ERR, "sf_connect failed");
241                 return FALSE;
242         }
243
244 #ifdef _POLLING_PROXIMITY_SENSOR_
245         my_cond.cond_op = CONDITION_EQUAL;
246         my_cond.cond_value1 = 200;
247         ret = sf_register_event(handle, PROXIMITY_EVENT_CHANGE_STATE, &my_cond, __voicecall_dvc_proximity_sensor_callback_func, pcall_core);
248 #else
249         ret = sf_register_event(handle, PROXIMITY_EVENT_CHANGE_STATE, NULL, __voicecall_dvc_proximity_sensor_callback_func, pcall_core);
250 #endif
251         if (ret < 0) {
252                 CALL_ENG_DEBUG(ENG_ERR, "sf_register_event failed");
253                 return FALSE;
254         }
255
256         ret = sf_start(handle, 0);
257         if (ret < 0) {
258                 CALL_ENG_DEBUG(ENG_ERR, "sensor_start fail");
259                 return FALSE;
260         }
261
262         ret = sf_get_data(handle, PROXIMITY_BASE_DATA_SET, &cur_sensor_data);
263         if (ret < 0) {
264                 CALL_ENG_DEBUG(ENG_ERR, "sf_get_data fail");
265                 return FALSE;
266         }
267
268         CALL_ENG_DEBUG(ENG_DEBUG, "proximity_state:[%d]\n", cur_sensor_data.values[0]);
269         if (cur_sensor_data.values[0] == PROXIMITY_STATE_NEAR) {
270                 if (__voicecall_dvc_proximity_sensor_is_required(pcall_core)) {
271                         CALL_ENG_DEBUG(ENG_DEBUG, "PROXIMITY_STATE_NEAR");
272                         g_proximity_sensor_state = VCALL_SENSOR_NEAR;
273                         _voicecall_dvc_control_lcd_state(VC_LCD_OFF);
274                 }
275         }
276
277         g_proximity_sensor_handle = handle;
278         CALL_ENG_DEBUG(ENG_DEBUG, "_voicecall_dvc_proximity_sensor_init done");
279 }
280
281 gboolean __voicecall_dvc_proximity_sensor_is_required(call_vc_core_state_t *pcall_core)
282 {
283         voicecall_engine_t *pcall_engine = NULL;
284         CALL_ENG_DEBUG(ENG_DEBUG, "");
285
286         if (pcall_core == NULL) {
287                 CALL_ENG_DEBUG(ENG_ERR, "Wrong pointer for pcall_core");
288                 return FALSE;
289         }
290
291         pcall_engine = pcall_core->pcall_engine;
292         if (pcall_engine == NULL) {
293                 CALL_ENG_DEBUG(ENG_ERR, "Wrong pointer for pcall_engine");
294                 return FALSE;
295         }
296
297         if (_vc_core_cm_isexists_incoming_call(&(pcall_engine->call_manager)) == TRUE) {
298                 CALL_ENG_DEBUG(ENG_DEBUG, "we'll not excute sensor in case of incoming call");
299                 return FALSE;
300         }
301
302         if ((_vc_core_cm_isexists_connected_call(&(pcall_engine->call_manager)) == FALSE) &&
303                 (_vc_core_cm_isexits_outgoing_call(&(pcall_engine->call_manager)) == FALSE)) {
304                 CALL_ENG_DEBUG(ENG_DEBUG, "we'll not excute sensor in case of NO call");
305                 return FALSE;
306         }
307
308         if (voicecall_snd_get_path_status(pcall_core->papp_snd) == VOICE_CALL_SND_PATH_SPEAKER) {
309                 CALL_ENG_DEBUG(ENG_DEBUG, "we'll not excute sensor in case of speaker mode");
310                 return FALSE;
311         }
312
313         return TRUE;
314 }
315
316 gboolean _voicecall_dvc_proximity_sensor_deinit(void)
317 {
318         CALL_ENG_DEBUG(ENG_DEBUG, "..");
319         int ret = -1;
320
321         if (g_proximity_sensor_handle < 0) {
322                 CALL_ENG_DEBUG(ENG_WARN, "not initialized.");
323                 return FALSE;
324         }
325
326         ret = sf_unregister_event(g_proximity_sensor_handle, PROXIMITY_EVENT_CHANGE_STATE);
327         if (ret < 0) {
328                 CALL_ENG_DEBUG(ENG_ERR, "sf_unregister_event failed");
329         }
330         ret = sf_stop(g_proximity_sensor_handle);
331         if (ret < 0) {
332                 CALL_ENG_DEBUG(ENG_ERR, "sf_stop failed");
333         }
334         ret = sf_disconnect(g_proximity_sensor_handle);
335         if (ret < 0) {
336                 CALL_ENG_DEBUG(ENG_ERR, "sf_disconnect failed");
337         }
338
339         g_proximity_sensor_handle = -1;
340         return TRUE;
341 }
342
343 static void __voicecall_dvc_proximity_sensor_callback_func(unsigned int type, sensor_event_data_t *event, void *data)
344 {
345         int *proxi_state;
346         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)data;
347         voicecall_engine_t *pcall_engine = NULL;
348         CALL_ENG_DEBUG(ENG_DEBUG, "");
349
350         if (__voicecall_dvc_proximity_sensor_is_required(pcall_core) == FALSE) {
351                 CALL_ENG_DEBUG(ENG_DEBUG, "Proximity sensor update is not required");
352                 return;
353         }
354
355         if (type != PROXIMITY_EVENT_CHANGE_STATE) {
356                 return;
357         }
358
359         proxi_state = (int *)(event->event_data);
360         switch (*proxi_state) {
361         case PROXIMITY_STATE_FAR:
362                 CALL_ENG_DEBUG(ENG_DEBUG, "PROXIMITY_STATE_FAR");
363                 g_proximity_sensor_state = VCALL_SENSOR_FAR;
364                 _voicecall_dvc_control_lcd_state(VC_LCD_ON);
365                 break;
366         case PROXIMITY_STATE_NEAR:
367                 CALL_ENG_DEBUG(ENG_DEBUG, "PROXIMITY_STATE_NEAR");
368                 g_proximity_sensor_state = VCALL_SENSOR_NEAR;
369                 _voicecall_dvc_control_lcd_state(VC_LCD_OFF);
370                 break;
371         default:
372                 CALL_ENG_DEBUG(ENG_DEBUG, "wrong data");
373                 break;
374         }
375 }
376
377 int _voicecall_dvc_get_proximity_sensor_state(void)
378 {
379         CALL_ENG_DEBUG(ENG_DEBUG, "g_proximity_sensor_state(%d)", g_proximity_sensor_state);
380
381         return g_proximity_sensor_state;
382 }