Make TIZEN 2.0
[apps/home/call.git] / call-engine / voice-call-service.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-service.h"
19 #include "voice-call-dbus.h"
20 #include "vc-core-util.h"
21 #include "voice-call-core.h"
22 #include "voice-call-sound.h"
23 #include "voice-call-bt.h"
24
25 /*
26  *  If the birthday is Today then it will return 0
27  *  If the birthday is within 1 week gap then it will return between 1 to 7
28  *  In all other cases it will return -1
29  */
30 static int __voicecall_service_get_bday_remaining_days(CTSstruct *contact)
31 {
32         int diff = -1;
33         GSList *event_list = NULL;
34         GSList *cursor = NULL;
35
36         contacts_svc_struct_get_list(contact, CTS_CF_EVENT_LIST, &event_list);
37         for (cursor = event_list; cursor; cursor = cursor->next) {
38                 if (CTS_EVENT_TYPE_BIRTH == contacts_svc_value_get_int(cursor->data, CTS_EVENT_VAL_TYPE_INT)) {
39                         int bday_date;
40                         time_t t_now;
41                         time_t t_bday;
42                         struct tm *timeinfo;
43                         bday_date = contacts_svc_value_get_int(cursor->data, CTS_EVENT_VAL_DATE_INT);
44                         time(&t_now);
45                         timeinfo = localtime(&t_now);
46                         timeinfo->tm_sec = timeinfo->tm_min = 59;
47                         timeinfo->tm_hour = 23;
48                         timeinfo->tm_mday = bday_date % 100;
49                         timeinfo->tm_mon = (bday_date%10000)/100 - 1;
50                         CALL_ENG_DEBUG(ENG_DEBUG, "bday date = %d, month = %d", timeinfo->tm_mday, timeinfo->tm_mon);
51                         t_bday = mktime(timeinfo);
52                         if (t_now < t_bday) {
53                                 diff = (int)((t_bday - t_now) / (24 * 60 * 60));
54                                 if (diff < 0 || diff > 7) {
55                                         diff = -1;      /* All the other days which dont fall in one week gap is invalid */
56                                 }
57                         } else {
58                                 CALL_ENG_DEBUG(ENG_DEBUG, "No need to show bday icon, becauae bday is not falling in 1 week gap");
59                         }
60
61                         break;
62                 }
63         }
64
65         CALL_ENG_DEBUG(ENG_DEBUG, "diff = %d", diff);
66         return diff;
67 }
68
69 /**
70  * This function gets  contact info from phone number
71  *
72  * @return              gboolean
73  * @param[in]           phonenumber             phone number
74  * @param[out]  ct_info                 contact info
75  */
76 gboolean voicecall_service_contact_info_by_number(char *phonenumber, voicecall_contact_info_t * ct_info)
77 {
78         CALL_ENG_KPI("voicecall_service_contact_info_by_number start");
79         int index = 0;
80         int ret = -1;
81         CTSstruct *contact = NULL;
82         CTSvalue *name = NULL, *base = NULL;
83         const char *first = NULL, *last = NULL, *display = NULL;
84         GSList *get_list, *cursor;
85
86         VOICECALL_RETURN_FALSE_IF_FAIL(phonenumber != NULL);
87         VOICECALL_RETURN_FALSE_IF_FAIL(ct_info != NULL);
88
89         CALL_ENG_DEBUG(ENG_DEBUG, "num:[%s],index:[%d]..", phonenumber, ct_info->ct_index);
90
91         contacts_svc_connect();
92
93         if (ct_info->ct_index == -1) {
94                 index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, phonenumber);
95                 if (index < CTS_SUCCESS) {
96                         CALL_ENG_DEBUG(ENG_DEBUG, "ret:[%d]..No found record", ret);
97                         ct_info->ct_index = -1;
98                         ct_info->phone_type = -1;
99                         ct_info->bday_remaining_days = -1;
100                         return FALSE;
101                 } else
102                         ct_info->ct_index = index;
103         }
104
105         ret = contacts_svc_get_contact(ct_info->ct_index, &contact);
106
107         if (ret < 0) {
108                 CALL_ENG_DEBUG(ENG_DEBUG, "ret:[%d]..No found record", ret);
109                 ct_info->ct_index = -1;
110                 ct_info->phone_type = -1;
111                 return FALSE;
112         }
113         /* If it comes to here, it means we have found a contact. */
114         contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &name);
115         first = contacts_svc_value_get_str(name, CTS_NAME_VAL_FIRST_STR);
116         last = contacts_svc_value_get_str(name, CTS_NAME_VAL_LAST_STR);
117         display = contacts_svc_value_get_str(name, CTS_NAME_VAL_DISPLAY_STR);
118
119         if (display != NULL) {
120                 snprintf(ct_info->display_name, sizeof(ct_info->display_name), "%s", display);
121         } else {
122                 if (first != NULL && last != NULL) {
123                         if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
124                                 snprintf(ct_info->display_name, sizeof(ct_info->display_name), "%s %s", first, last);
125                         else
126                                 snprintf(ct_info->display_name, sizeof(ct_info->display_name), "%s %s", last, first);
127                 } else if (first == NULL && last != NULL) {
128                         snprintf(ct_info->display_name, sizeof(ct_info->display_name), "%s", last);
129                 } else if (first != NULL && last == NULL) {
130                         snprintf(ct_info->display_name, sizeof(ct_info->display_name), "%s", first);
131                 } else {
132                         CALL_ENG_DEBUG(ENG_DEBUG, "Error!. first & last name is NULL!!");
133                         snprintf(ct_info->display_name, sizeof(ct_info->display_name), "%s", "no name");
134                 }
135         }
136         get_list = NULL;
137         contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &get_list);
138         cursor = get_list;
139         while (cursor) {
140                 if (strcmp(contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR), phonenumber) == 0) {
141                         ct_info->phone_type = contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT);
142                 }
143                 cursor = cursor->next;
144                 if (cursor == NULL)
145                         break;
146         }
147
148         contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base);
149
150         _vc_core_util_strcpy(ct_info->caller_id_path, sizeof(ct_info->caller_id_path), contacts_svc_value_get_str(base, CTS_BASE_VAL_IMG_PATH_STR));
151
152         char *full_path = NULL;
153         contacts_svc_get_image(CTS_IMG_FULL, ct_info->ct_index, &full_path);
154         if (full_path != NULL) {
155                 _vc_core_util_strcpy(ct_info->caller_full_id_path, sizeof(ct_info->caller_full_id_path), full_path);
156         }
157         free(full_path);
158
159         _vc_core_util_strcpy(ct_info->ring_tone, sizeof(ct_info->ring_tone), contacts_svc_value_get_str(base, CTS_BASE_VAL_RINGTONE_PATH_STR));
160
161         ct_info->bday_remaining_days = __voicecall_service_get_bday_remaining_days(contact);
162
163         CALL_ENG_DEBUG(ENG_DEBUG, "contact index:[%d]", ct_info->ct_index);
164         CALL_ENG_DEBUG(ENG_DEBUG, "phone_type:[%d]", ct_info->phone_type);
165         CALL_ENG_DEBUG(ENG_DEBUG, "bday_remaining_days :[%d]", ct_info->bday_remaining_days);
166         CALL_ENG_DEBUG(ENG_DEBUG, "display name:[%s]", ct_info->display_name);
167         CALL_ENG_DEBUG(ENG_DEBUG, "img path:[%s]", ct_info->caller_id_path);
168         CALL_ENG_DEBUG(ENG_DEBUG, "full img path:[%s]", ct_info->caller_full_id_path);
169         CALL_ENG_DEBUG(ENG_DEBUG, "ringtone path:[%s]", ct_info->ring_tone);
170
171         contacts_svc_struct_free(contact);
172         contacts_svc_disconnect();
173         CALL_ENG_DEBUG(ENG_DEBUG, "Ended!!");
174         CALL_ENG_KPI("voicecall_service_contact_info_by_number done");
175         return TRUE;
176 }
177
178 /**
179  * This function gets  contact info from contact id
180  *
181  * @return              gboolean
182  * @param[in]           phonenumber             phone number
183  * @param[in]           contact_id              contact id
184  * @param[in]           storage_type            storage type
185  * @param[out]  ct_info                 contact info
186  */
187 gboolean voicecall_service_contact_info_by_contact_id(char *phonenumber, int contact_id, voicecall_contact_info_t * ct_info)
188 {
189 #ifdef _CT_SEARCH_BY_ID_
190         VOICECALL_RETURN_FALSE_IF_FAIL(phonenumber != NULL);
191         VOICECALL_RETURN_FALSE_IF_FAIL(ct_info != NULL);
192
193         int bfound = FALSE;
194         int ret;
195         contact_t record;
196         int index = 0;
197
198         CALL_ENG_DEBUG(ENG_DEBUG, "..");
199
200         memset(&record, 0, sizeof(contact_t));
201
202         if (contact_db_service_connect() != CONTACT_OPERATION_SUCCESS) {
203                 CALL_ENG_DEBUG(ENG_DEBUG, "contact_db_service_connect error");
204                 return FALSE;
205         }
206
207         ret = contact_db_service_contact_get(CONTACT_DB_GET_RECORD_BY_KEY, contact_id, storage_type, &record);
208
209         if (ret == CONTACT_OPERATION_SUCCESS) {
210                 bfound = TRUE;
211         } else {
212                 bfound = FALSE;
213         }
214
215         CALL_ENG_DEBUG(ENG_DEBUG, " bfound = [%d]", bfound);
216         if (bfound) {
217                 if (record.contact.display_name != NULL)
218                         _vc_core_util_strcpy(ct_info->display_name, sizeof(ct_info->display_name), record.contact.display_name);
219                 if (record.contact.media_data.ringtone_path != NULL)
220                         _vc_core_util_strcpy(ct_info->ring_tone, sizeof(ct_info->ring_tone), record.contact.media_data.ringtone_path);
221
222                 ct_info->ct_index = contact_id;
223                 ct_info->storage_type = storage_type;
224
225                 CALL_ENG_DEBUG(ENG_DEBUG, "phone count:[%d]", record.phone_count);
226                 for (index = 0; index < record.phone_count; index++) {
227                         if (strcmp(record.phone_info[index].number, phonenumber) == 0) {
228                                 ct_info->phone_type = record.phone_info[index].type;
229                         }
230                 }
231                 CALL_ENG_DEBUG(ENG_DEBUG, "***  found  ***");
232                 CALL_ENG_DEBUG(ENG_DEBUG, "name:[%s] vs [%s]", ct_info->display_name, record.contact.display_name);
233                 CALL_ENG_DEBUG(ENG_DEBUG, "ringtone path:[%s] vs [%s]", ct_info->ring_tone, record.contact.media_data.ringtone_path);
234         } else {
235                 ct_info->ct_index = contact_id;
236                 ct_info->storage_type = storage_type;
237                 ct_info->phone_type = -1;
238
239                 CALL_ENG_DEBUG(ENG_DEBUG, "not found. name:[%s], path:[%s]", ct_info->display_name, ct_info->caller_id_path);
240         }
241
242         contact_db_service_contact_free(&record);
243         if (contact_db_service_disconnect() != CONTACT_OPERATION_SUCCESS) {
244                 CALL_ENG_DEBUG(ENG_DEBUG, "contact_db_service_disconnect error");
245                 return FALSE;
246         }
247 #endif
248         return TRUE;
249 }
250
251 /**
252  * This function on the loud speaker state
253  *
254  * @return              gboolean
255  * @param[in]           pcall_core              Handle to voicecall core
256  */
257 gboolean voicecall_service_loudspeaker_on(call_vc_core_state_t *pcall_core)
258 {
259         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
260
261         voicecall_snd_mgr_t *papp_snd = pcall_core->papp_snd;
262         gboolean ret = FALSE;
263         int total_call_member = -1;
264
265         CALL_ENG_DEBUG(ENG_DEBUG, "");
266
267         voicecall_core_get_total_call_member(pcall_core->pcall_engine, &total_call_member);
268         if (total_call_member == 0) {
269                 CALL_ENG_DEBUG(ENG_DEBUG, "There are not active calls hence it should not work");
270                 return FALSE;
271         }
272
273         /* Toggle the LoudSpeaker Status */
274         if (voicecall_snd_get_path_status(pcall_core->papp_snd) != VOICE_CALL_SND_PATH_SPEAKER) {
275                 if (TRUE == _vc_bt_is_bt_connected(pcall_core) &&
276                 (voicecall_snd_get_path_status(pcall_core->papp_snd) == VOICE_CALL_SND_PATH_BT)) {
277                         voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_SPEAKER);
278 /*                      _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_SWITCH_TO_PHONE, -1, NULL);*/
279                         _vc_bt_request_switch_headset_path(pcall_core, FALSE);
280                 } else {
281                         voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_SPEAKER);
282                         voicecall_snd_change_path(papp_snd);
283                 }
284         } else {
285                 CALL_ENG_DEBUG(ENG_DEBUG, "loudspeacker is already on.");
286                 ret = FALSE;
287         }
288         return ret;
289 }
290
291 /**
292  * This function off the loud speaker state
293  *
294  * @return              gboolean
295  * @param[in]           pcall_core              Handle to voicecall core
296  */
297 gboolean voicecall_service_loudspeaker_off(call_vc_core_state_t *pcall_core)
298 {
299         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
300
301         gboolean ret = FALSE;
302         voicecall_snd_mgr_t *papp_snd = pcall_core->papp_snd;
303         int total_call_member = -1;
304         voicecall_core_get_total_call_member(pcall_core->pcall_engine, &total_call_member);
305         if (total_call_member == 0) {
306                 CALL_ENG_DEBUG(ENG_DEBUG, "There are not active calls hence it should not work");
307                 return FALSE;
308         }
309
310         CALL_ENG_DEBUG(ENG_DEBUG, "");
311
312                 if (voicecall_snd_get_path_status(pcall_core->papp_snd) == VOICE_CALL_SND_PATH_SPEAKER) {
313                         if (TRUE == _vc_bt_is_bt_connected(pcall_core)) {
314                                 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_BT);
315                                 /*_vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_SWITCH_TO_HEADSET, -1, NULL);*/
316                                 _vc_bt_request_switch_headset_path(pcall_core, TRUE);
317                         } else {
318                                 CALL_ENG_DEBUG(ENG_DEBUG, "Set VOICE_CALL_SND_PATH_RECEIVER_EARJACK");
319                                 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_RECEIVER_EARJACK);
320                                 voicecall_snd_change_path(papp_snd);
321                         }
322                 } else {
323                         CALL_ENG_DEBUG(ENG_DEBUG, "loudspeacker is already on.");
324                         ret = FALSE;
325                 }
326         return ret;
327 }
328
329 /**
330  * This function is mute on
331  *
332  * @return              void
333  * @param[in]           pcall_core              Handle to voicecall core
334  */
335
336 gboolean voicecall_service_mute_status_on(call_vc_core_state_t *pcall_core)
337 {
338         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
339
340         gboolean bactive_calls = FALSE;
341         gboolean bheld_calls = FALSE;
342
343         voicecall_snd_mgr_t *papp_snd = pcall_core->papp_snd;
344         voicecall_engine_t *pcall_engine = pcall_core->pcall_engine;
345
346         CALL_ENG_DEBUG(ENG_DEBUG, "..");
347
348         voicecall_core_is_call_exists(pcall_engine, &bactive_calls, &bheld_calls);
349
350         if (FALSE == bactive_calls && TRUE == bheld_calls) {
351                 CALL_ENG_DEBUG(ENG_DEBUG, "nothing to do.");
352                 /*Mute button should not be handled if only held calls exists */
353                 return TRUE;
354         }
355
356         if (FALSE == papp_snd->bmute_status) {
357                 CALL_ENG_DEBUG(ENG_DEBUG, "Setting Voice Audio Mute Status On.");
358                 voicecall_core_set_audio_mute_status(pcall_engine, TRUE);
359                 papp_snd->bmute_status = TRUE;
360                 return TRUE;
361         } else {
362                 CALL_ENG_DEBUG(ENG_DEBUG, "mute status is already on.");
363                 return FALSE;
364         }
365
366 }
367
368 /**
369  * This function is mute off
370  *
371  * @return              void
372  * @param[in]           pcall_core              Handle to voicecall core
373  */
374 gboolean voicecall_service_mute_status_off(call_vc_core_state_t *pcall_core)
375 {
376         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
377
378         gboolean bactive_calls = FALSE;
379         gboolean bheld_calls = FALSE;
380
381         voicecall_snd_mgr_t *papp_snd = pcall_core->papp_snd;
382         voicecall_engine_t *pcall_engine = pcall_core->pcall_engine;
383
384         CALL_ENG_DEBUG(ENG_DEBUG, "..");
385
386         voicecall_core_is_call_exists(pcall_engine, &bactive_calls, &bheld_calls);
387
388         if (FALSE == bactive_calls && TRUE == bheld_calls) {
389                 CALL_ENG_DEBUG(ENG_DEBUG, "nothing to do.");
390                 /*Mute button should not be handled if only held calls exists */
391                 return TRUE;
392         }
393
394         if (TRUE == papp_snd->bmute_status) {
395                 CALL_ENG_DEBUG(ENG_DEBUG, "Setting Voice Audio Mute Status Off.");
396                 voicecall_core_set_audio_mute_status(pcall_engine, FALSE);
397                 papp_snd->bmute_status = FALSE;
398                 return TRUE;
399         } else {
400                 CALL_ENG_DEBUG(ENG_DEBUG, "mute status is already off.");
401                 return FALSE;
402         }
403
404 }
405
406 /**
407  * This function set volume level.
408  *
409  * @return              Returns TRUE on success or FALSE on failure
410  * @param[in]           pcall_core                      Handle to voicecall core
411  * @param[in]           vol_alert_type                  volume alert type
412  * @param[in]           volume_level                    volume level to be set
413  */
414 gboolean voicecall_service_set_volume(call_vc_core_state_t *pcall_core, voicecall_snd_volume_alert_type_t vol_alert_type, int volume_level)
415 {
416         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
417
418         voicecall_snd_mgr_t *papp_snd = pcall_core->papp_snd;
419
420         voicecall_snd_set_volume(papp_snd, vol_alert_type, volume_level);
421
422         return TRUE;
423 }
424