Apply new contacts-service db.
[platform/core/messaging/msg-service.git] / utils / MsgContact.cpp
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 extern "C"
18 {
19         #include <contacts-svc.h>
20 }
21
22 #include "MsgDebug.h"
23 #include "MsgUtilStorage.h"
24 #include "MsgGconfWrapper.h"
25 #include "MsgContact.h"
26
27
28 /*==================================================================================================
29                                      VARIABLES
30 ==================================================================================================*/
31 static bool isContactSvcOpened = false;
32
33 MsgDbHandler ContactDbHandle;
34
35 MsgContactChangeCB cbFunction = NULL;
36 /*==================================================================================================
37                                      FUNCTION IMPLEMENTATION
38 ==================================================================================================*/
39 static void MsgContactSvcCallback(void *pData)
40 {
41         MSG_DEBUG("Contact Data is Changed!!!");
42
43         MsgSyncContact();
44
45         if (ContactDbHandle.disconnect() != MSG_SUCCESS)
46                 MSG_DEBUG("DB Disconnect Fail");
47 }
48
49
50 msg_error_t MsgOpenContactSvc()
51 {
52         int errCode = CTS_SUCCESS;
53
54         if (!isContactSvcOpened) {
55                 errCode = contacts_svc_connect();
56
57                 if (errCode == CTS_SUCCESS) {
58                         MSG_DEBUG("Connect to Contact Service Success");
59                         isContactSvcOpened = true;
60                 } else {
61                         MSG_DEBUG("Connect to Contact Service Fail [%d]", errCode);
62                         isContactSvcOpened = false;
63                         return MSG_ERR_DB_CONNECT;
64                 }
65         } else {
66                 MSG_DEBUG("Already connected to Contact Service.");
67         }
68
69         return MSG_SUCCESS;
70 }
71
72
73 msg_error_t MsgCloseContactSvc()
74 {
75         int errCode = CTS_SUCCESS;
76
77         if (isContactSvcOpened) {
78                 errCode = contacts_svc_disconnect();
79
80                 if (errCode == CTS_SUCCESS) {
81                         MSG_DEBUG("Disconnect to Contact Service Success");
82                 } else {
83                         MSG_DEBUG("Disconnect to Contact Service Fail [%d]", errCode);
84                         return MSG_ERR_DB_DISCONNECT;
85                 }
86         }
87
88         return MSG_SUCCESS;
89 }
90
91
92 msg_error_t MsgInitContactSvc(MsgContactChangeCB cb)
93 {
94         int errCode = CTS_SUCCESS;
95
96         if (cb != NULL)
97                 cbFunction = cb;
98
99         // Register callback function
100         errCode = contacts_svc_subscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE, MsgContactSvcCallback, NULL);
101
102         if (errCode == CTS_SUCCESS)
103                 MSG_DEBUG("Register Contact Service Callback");
104         else
105                 MSG_DEBUG("Fail to Register Contact Service Callback [%d]", errCode);
106
107         return MSG_SUCCESS;
108 }
109
110
111 msg_error_t MsgGetContactInfo(const MSG_ADDRESS_INFO_S *pAddrInfo, MSG_CONTACT_INFO_S *pContactInfo)
112 {
113         MSG_BEGIN();
114
115         MSG_DEBUG("Address Type [%d], Address Value [%s]", pAddrInfo->addressType, pAddrInfo->addressVal);
116
117         memset(pContactInfo, 0x00, sizeof(MSG_CONTACT_INFO_S));
118
119         if (pAddrInfo->addressType == MSG_ADDRESS_TYPE_PLMN && strlen(pAddrInfo->addressVal) > (MAX_PHONE_NUMBER_LEN+1)) {
120                 MSG_DEBUG("Phone Number is too long [%s]", pAddrInfo->addressVal);
121                 return MSG_ERR_INVALID_PARAMETER;
122         }
123
124         int index, ret = -1;
125
126         CTSstruct* contact = NULL;
127
128         cts_find_op recordType;
129
130         if (pAddrInfo->addressType == MSG_ADDRESS_TYPE_EMAIL)
131                 recordType = CTS_FIND_BY_EMAIL;
132         else
133                 recordType = CTS_FIND_BY_NUMBER;
134
135         index = contacts_svc_find_contact_by(recordType, (char*)pAddrInfo->addressVal);
136
137         if (index > CTS_SUCCESS) {
138                 MSG_DEBUG("Index : [%d]", index);
139                 ret = contacts_svc_get_contact(index, &contact);
140         }
141
142         if (ret < 0) {
143                 MSG_DEBUG("No Contact Info");
144                 return MSG_SUCCESS;
145         }
146
147         CTSvalue* name = NULL;
148
149         ret = contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &name);
150
151         if (ret != CTS_SUCCESS) {
152                 MSG_DEBUG("contacts_svc_struct_get_value() Error [%d]", ret);
153                 return MSG_SUCCESS;
154         }
155
156         const char* strFirstName = contacts_svc_value_get_str(name, CTS_NAME_VAL_FIRST_STR);
157         const char* strLastName = contacts_svc_value_get_str(name, CTS_NAME_VAL_LAST_STR);
158
159         MSG_DEBUG("First Name : [%s], Last Name : [%s]", strFirstName, strLastName);
160
161         if (strFirstName != NULL)
162                 strncpy(pContactInfo->firstName, strFirstName, MAX_DISPLAY_NAME_LEN);
163
164         if (strLastName != NULL)
165                 strncpy(pContactInfo->lastName, strLastName, MAX_DISPLAY_NAME_LEN);
166
167         CTSvalue* base = NULL;
168
169         ret = contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base);
170
171         if (ret != CTS_SUCCESS) {
172                 MSG_DEBUG("contacts_svc_struct_get_value() Error [%d]", ret);
173                 return MSG_SUCCESS;
174         }
175
176         pContactInfo->contactId = contacts_svc_value_get_int(base, CTS_BASE_VAL_ID_INT);
177
178         MSG_DEBUG("Contact ID [%d]", pContactInfo->contactId);
179
180         const char* strImagePath = contacts_svc_value_get_str(base, CTS_BASE_VAL_IMG_PATH_STR);
181
182         if (strImagePath != NULL)
183                 strncpy(pContactInfo->imagePath , strImagePath, MAX_IMAGE_PATH_LEN);
184
185         MSG_DEBUG("Image Path [%s]", pContactInfo->imagePath);
186
187         contacts_svc_value_free(base);
188         contacts_svc_value_free(name);
189
190         contacts_svc_struct_free(contact);
191
192         MSG_END();
193
194         return MSG_SUCCESS;
195 }
196
197
198 void MsgSyncContact()
199 {
200         int ret = -1;
201         int index_num = 0;
202         int changed_count = 0;
203         int lastSyncTime = 0;
204
205         /* get contact sync time */
206         lastSyncTime = MsgSettingGetInt(CONTACT_SYNC_TIME);
207
208         if (lastSyncTime < 0) {
209                 MSG_DEBUG("Fail to get CONTACT_SYNC_TIME.");
210                 lastSyncTime = 0;
211         }
212
213         CTSiter* pIter;
214
215         ret = contacts_svc_get_updated_contacts(-1, lastSyncTime, &pIter);
216
217         if (ret != CTS_SUCCESS) {
218                 MSG_DEBUG("contacts_svc_get_updated_contacts() Error [%d]", ret);
219                 return;
220         }
221
222         while (contacts_svc_iter_next(pIter) == CTS_SUCCESS)
223         {
224                 CTSvalue *row_info = NULL;
225
226                 row_info = contacts_svc_iter_get_info(pIter);
227
228                 index_num = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
229
230                 MSG_DEBUG("index (%d)", index_num);
231
232                 int type = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TYPE_INT);
233
234                 if (type == CTS_OPERATION_UPDATED || type == CTS_OPERATION_INSERTED) {
235                         MsgUpdateContact(index_num, type);
236                 } else {// Delete
237                         MSG_DEBUG("Delete Contact");
238                         MsgDeleteContact(index_num);
239                 }
240
241                 if(lastSyncTime < contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_VER_INT))
242                         lastSyncTime = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_VER_INT);
243
244                 contacts_svc_value_free(row_info);
245
246                 changed_count++;
247         }
248
249         MsgSettingSetInt(CONTACT_SYNC_TIME, lastSyncTime);
250         MSG_DEBUG("lastSyncTime : %d", lastSyncTime);
251
252         contacts_svc_iter_remove(pIter);
253
254         if(changed_count > 0)
255                 cbFunction();
256 }
257
258
259 bool MsgInsertContact(MSG_CONTACT_INFO_S *pContactInfo, const char *pNumber)
260 {
261         if (!pNumber || strlen(pNumber) <= 0)
262                 return false;
263
264         if (MsgStoAddContactInfo(&ContactDbHandle, pContactInfo, pNumber) != MSG_SUCCESS) {
265                 MSG_DEBUG("Fail to add contact info.");
266                 return false;
267         }
268
269         return true;
270 }
271
272
273 bool MsgUpdateContact(int index, int type)
274 {
275         int ret = -1;
276
277         CTSstruct *contact = NULL;
278
279         ret = contacts_svc_get_contact(index, &contact);
280
281         if (ret != CTS_SUCCESS) {
282                 MSG_DEBUG("contacts_svc_get_contact() Error [%d]", ret);
283                 return false;
284         }
285
286         // Base Info
287         CTSvalue *base = NULL;
288
289         ret = contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base);
290
291         if (ret != CTS_SUCCESS) {
292                 MSG_DEBUG("contacts_svc_struct_get_value() Error [%d]", ret);
293                 return false;
294         }
295
296         MSG_CONTACT_INFO_S contactInfo = {0};
297
298         contactInfo.contactId = contacts_svc_value_get_int(base, CTS_BASE_VAL_ID_INT);
299
300         MSG_DEBUG("Contact ID [%d]", contactInfo.contactId);
301
302         const char* strImagePath = contacts_svc_value_get_str(base, CTS_BASE_VAL_IMG_PATH_STR);
303
304         if (strImagePath != NULL)
305                 strncpy(contactInfo.imagePath , strImagePath, MAX_IMAGE_PATH_LEN);
306
307         MSG_DEBUG("Image Path [%s]", contactInfo.imagePath);
308
309         // Name Info
310         CTSvalue* name = NULL;
311
312         ret = contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &name);
313
314         if (ret != CTS_SUCCESS) {
315                 MSG_DEBUG("contacts_svc_struct_get_value() Error [%d]", ret);
316                 return MSG_SUCCESS;
317         }
318
319         const char* strFirstName = contacts_svc_value_get_str(name, CTS_NAME_VAL_FIRST_STR);
320         const char* strLastName = contacts_svc_value_get_str(name, CTS_NAME_VAL_LAST_STR);
321
322         MSG_DEBUG("First Name : [%s], Last Name : [%s]", strFirstName, strLastName);
323
324         if (strFirstName != NULL)
325                 strncpy(contactInfo.firstName, strFirstName, MAX_DISPLAY_NAME_LEN);
326
327         if (strLastName != NULL)
328                 strncpy(contactInfo.lastName, strLastName, MAX_DISPLAY_NAME_LEN);
329
330         MsgStoClearContactInfo(&ContactDbHandle, index);
331
332         GSList *get_list, *cursor;
333
334         get_list = NULL;
335
336         contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &get_list);
337
338         cursor = get_list;
339
340         // No phone number in contact
341         if (cursor == NULL) {
342                  contacts_svc_struct_free(contact);
343                 return true;
344         }
345
346         for(; cursor; cursor = g_slist_next(cursor))
347         {
348                 MSG_DEBUG("Add Contact Data");
349
350                 const char* strNumber = contacts_svc_value_get_str((CTSvalue*)cursor->data, CTS_NUM_VAL_NUMBER_STR);
351
352                 MSG_DEBUG("Number = %s", strNumber);
353
354                 if (MsgInsertContact(&contactInfo, strNumber) == false)
355                         continue;
356         }
357
358         MsgStoSetConversationDisplayName(&ContactDbHandle, index);
359
360         contacts_svc_struct_free(contact);
361
362         return true;
363 }
364
365
366 bool MsgDeleteContact(int index)
367 {
368         if (MsgStoClearContactInfo(&ContactDbHandle, index) != MSG_SUCCESS)
369                 return false;
370
371         return true;
372 }
373
374
375 int MsgGetContactNameOrder()
376 {
377         int ret = 0;
378
379         cts_order_type order = CTS_ORDER_NAME_FIRSTLAST;
380
381         order = contacts_svc_get_order(CTS_ORDER_OF_DISPLAY);
382
383         if (order == CTS_ORDER_NAME_FIRSTLAST)
384                 ret = 0;
385         else if (order == CTS_ORDER_NAME_LASTFIRST)
386                 ret = 1;
387
388         return ret;
389 }
390
391
392 msg_error_t MsgAddPhoneLog(const MSG_MESSAGE_INFO_S *pMsgInfo)
393 {
394         msg_error_t err = MSG_SUCCESS;
395
396         MSG_DEBUG("folderId [%d], number [%s]", pMsgInfo->folderId, pMsgInfo->addressList[0].addressVal);
397
398         CTSvalue* plog;
399
400         plog = contacts_svc_value_new(CTS_VALUE_PHONELOG);
401
402         contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, (char*)pMsgInfo->addressList[0].addressVal);
403         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT, (int)time(NULL));
404
405         char strText[101];
406         memset(strText, 0x00, sizeof(strText));
407
408         if (pMsgInfo->msgType.mainType == MSG_SMS_TYPE) {
409                 strncpy(strText, pMsgInfo->msgText, 100);
410                 MSG_DEBUG("msgText : %s", strText);
411         } else if (pMsgInfo->msgType.mainType == MSG_MMS_TYPE) {
412                 if (strlen(pMsgInfo->subject) > 0 || pMsgInfo->msgType.subType == MSG_NOTIFICATIONIND_MMS) {
413                         strncpy(strText, pMsgInfo->subject, 100);
414                         MSG_DEBUG("subject : %s", strText);
415                 } else {
416                         strncpy(strText, pMsgInfo->msgText, 100);
417                         MSG_DEBUG("msgText : %s", strText);
418                 }
419         }
420
421         contacts_svc_value_set_str(plog, CTS_PLOG_VAL_SHORTMSG_STR, strText);
422         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_MSGID_INT, (int)pMsgInfo->msgId);
423
424         if (pMsgInfo->folderId == MSG_INBOX_ID) {
425                 if (pMsgInfo->msgType.mainType == MSG_SMS_TYPE)
426                         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT, CTS_PLOG_TYPE_SMS_INCOMMING);
427                 else if (pMsgInfo->msgType.mainType == MSG_MMS_TYPE)
428                         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT, CTS_PLOG_TYPE_MMS_INCOMMING);
429         } else if (pMsgInfo->folderId == MSG_OUTBOX_ID) {
430                 if (pMsgInfo->msgType.mainType == MSG_SMS_TYPE)
431                         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT, CTS_PLOG_TYPE_SMS_OUTGOING);
432                 else if (pMsgInfo->msgType.mainType == MSG_MMS_TYPE)
433                         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT, CTS_PLOG_TYPE_MMS_OUTGOING);
434         } else if (pMsgInfo->folderId == MSG_SPAMBOX_ID) {
435                 if (pMsgInfo->msgType.mainType == MSG_SMS_TYPE)
436                         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT, CTS_PLOG_TYPE_SMS_BLOCKED);
437                 else if (pMsgInfo->msgType.mainType == MSG_MMS_TYPE)
438                         contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT, CTS_PLOG_TYPE_MMS_BLOCKED);
439         }
440
441         int ret = contacts_svc_insert_phonelog(plog);
442
443         if (ret != CTS_SUCCESS)
444                 MSG_DEBUG("contacts_svc_insert_phonelog() Failed!!! [%d]", ret);
445
446         contacts_svc_value_free(plog);
447
448         return err;
449 }
450
451
452 msg_error_t MsgDeletePhoneLog(msg_message_id_t msgId)
453 {
454         msg_error_t err = MSG_SUCCESS;
455
456         MSG_DEBUG("MsgDeletePhoneLog [%d]", msgId);
457
458         int ret = contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_MSGID, msgId);
459
460         if (ret != CTS_SUCCESS)
461                 MSG_DEBUG("contacts_svc_delete_phonelog() Failed!!! [%d]", ret);
462
463         return err;
464 }
465
466
467 int MsgContactSVCBeginTrans()
468 {
469         return contacts_svc_begin_trans();
470 }
471
472
473 int MsgContactSVCEndTrans(bool bSuccess)
474 {
475         return contacts_svc_end_trans(bSuccess);
476 }