b2bab6033930033cc60e6bb966aa7b9fe0462dc2
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Contact / ContactListenerManager.cpp
1 /*
2  * Copyright (c) 2011 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  * @file        ContactListenerManager.cpp
18  * @author      Kisub Song (kisubs.song@samsung.com)
19  * @version     0.1
20  * @brief       
21  */
22
23 #include "ContactListenerManager.h"
24
25 #include <contacts-svc.h>
26
27 #include <dpl/log/log.h>
28 #include <dpl/singleton_impl.h>
29 #include <Commons/Exception.h>
30 #include <Commons/Regex.h>
31
32 #include "ContactUtility.h"
33 #include "ContactObjectP2AConverter.h"
34 #include "query-svc/query-service.h"
35
36 IMPLEMENT_SINGLETON(TizenApis::Platform::Contact::ContactListenerManager)
37
38 namespace TizenApis {
39 namespace Platform {
40 namespace Contact {
41
42 using namespace std;
43 using namespace WrtDeviceApis::Commons;
44 using namespace TizenApis::Api::Contact;
45
46 ContactListenerManager::ContactListenerManager() :
47                 m_callbackRegistered(false),
48                 m_latestVersion(0),
49                 m_watchIdAcc(0)
50 {
51 }
52
53 ContactListenerManager::~ContactListenerManager()
54 {
55         if(m_callbackRegistered)
56         {
57                 unregisterContactSvcChangedCallbacks();
58         }
59 }
60
61 void ContactListenerManager::registerAppListChangedCallbacks(IContactEventCallbacks *callbacks, int addressBookId)
62 {
63         if(callbacks == NULL)
64         {
65                 LogWarning("Parameter is NULL.");
66                 return;
67         }
68
69         if(getContactEventCallbacks(addressBookId) != NULL)
70                 ThrowMsg(PlatformException, "Already registered address book (id:" << addressBookId << ")");
71
72         if(!m_callbackRegistered)
73         {
74                 registerContactSvcChangedCallbacks();
75         }
76
77         m_callbacks[addressBookId] = callbacks;
78 }
79
80 void ContactListenerManager::unregisterAppListChangedCallbacks(IContactEventCallbacks *callbacks)
81 {
82         if(callbacks == NULL)
83         {
84                 LogWarning("Parameter is NULL.");
85                 return;
86         }
87
88         if(m_callbacks.size() == 0)
89         {
90                 LogWarning("No callbacks are registered.");
91                 return;
92         }
93
94         ContactEventCallbacksMap::iterator iter = m_callbacks.begin();
95         for(; iter != m_callbacks.end(); iter++)
96         {
97                 if(iter->second == callbacks)
98                         break;
99         }
100
101         if(iter == m_callbacks.end())
102         {
103                 LogWarning("Callbacks " << callbacks << " are not registered.");
104                 return;
105         }
106
107         m_callbacks.erase(iter);
108
109         if(m_callbacks.size() == 0)
110         {
111                 unregisterContactSvcChangedCallbacks();
112         }
113 }
114
115 void ContactListenerManager::unregisterAppListChangedCallbacks(int addressBookId)
116 {
117         if(m_callbacks.size() == 0)
118         {
119                 LogWarning("No callbacks are registered.");
120                 return;
121         }
122
123         ContactEventCallbacksMap::iterator iter = m_callbacks.find(addressBookId);
124         if(iter == m_callbacks.end())
125         {
126                 LogWarning("Callbacks for addressbook " << addressBookId << " are not registered.");
127                 return;
128         }
129
130         m_callbacks.erase(iter);
131
132         if(m_callbacks.size() == 0)
133         {
134                 unregisterContactSvcChangedCallbacks();
135         }
136 }
137
138 long ContactListenerManager::getWatchIdAndInc()
139 {
140         return ++m_watchIdAcc;
141 }
142
143 void ContactListenerManager::contactsSvcEventCallback(void *data)
144 {
145         if(data == NULL)
146         {
147                 LogWarning("contacts-service listener passed NULL user_data");
148                 return;
149         }
150
151         ContactListenerManager *contactListenerMgr = static_cast<ContactListenerManager *>(data);
152         contactListenerMgr->contactsSvcEventCallback();
153 }
154
155 void ContactListenerManager::contactsSvcEventCallback()
156 {
157         LogDebug("entered");
158         if(!m_callbackRegistered)
159                 return;
160
161         int errorCode = 0;
162
163         ContactEventCallbacksMap::iterator callbacksIter = m_callbacks.begin();
164         for(; callbacksIter != m_callbacks.end(); callbacksIter++)
165         {
166                 int addressBookId = callbacksIter->first;
167                 IContactEventCallbacks *callbacks = callbacksIter->second;
168
169                 CTSiter *iter = NULL;
170
171                 errorCode = contacts_svc_get_updated_contacts(addressBookId, m_latestVersion, &iter);
172                 if(errorCode != CTS_SUCCESS)
173                 {
174                         LogDebug("No updated contacts for addressbook : " << addressBookId);
175                         continue;
176                 }
177
178                 int changeId = 0;
179                 int changeType = 0;
180                 int changeVersion = 0;
181
182                 bool existingAddedContacts = false;
183                 bool existingUpdatedContacts = false;
184                 bool existingRemovedContacts = false;
185
186                 ContactArrayPtr addedContacts(new ContactArray());
187                 ContactArrayPtr updatedContacts(new ContactArray());
188                 StringArrayPtr removedContactIds(new StringArray());
189
190                 while (contacts_svc_iter_next(iter) == CTS_SUCCESS)
191                 {
192                         CTSstruct *contact= NULL;
193                         CTSvalue *row_info = NULL;
194                         row_info = contacts_svc_iter_get_info(iter);
195
196                         changeId = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
197                         changeType = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TYPE_INT);
198                         changeVersion = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_VER_INT);
199
200                         if(changeType == CTS_OPERATION_INSERTED)
201                         {
202                                 existingAddedContacts = true;
203                                 contacts_svc_get_contact(changeId, &contact);
204
205                                 ContactObjectP2AConverterPtr contactObjConverter(
206                                                 new ContactObjectP2AConverter(contact, false) );
207                                 ContactPtr absContact = contactObjConverter->getAbstractContact();
208                                 if(absContact != NULL)
209                                         addedContacts->push_back(absContact);
210
211                                 if(contact != NULL)
212                                 {
213                                         contacts_svc_struct_free(contact);
214                                         contact = NULL;
215                                 }
216                         }
217
218                         if(changeType == CTS_OPERATION_UPDATED)
219                         {
220                                 existingUpdatedContacts = true;
221                                 contacts_svc_get_contact(changeId, &contact);
222
223                                 ContactObjectP2AConverterPtr contactObjConverter(
224                                                 new ContactObjectP2AConverter(contact, false) );
225                                 ContactPtr absContact = contactObjConverter->getAbstractContact();
226                                 if(absContact != NULL)
227                                         updatedContacts->push_back(absContact);
228
229                                 if(contact != NULL)
230                                 {
231                                         contacts_svc_struct_free(contact);
232                                         contact = NULL;
233                                 }
234                         }
235
236                         if(changeType == CTS_OPERATION_DELETED)
237                         {
238                                 existingRemovedContacts = true;
239
240                                 removedContactIds->push_back(ContactUtility::intToStr(changeId));
241                         }
242
243                         contacts_svc_value_free(row_info);
244                 }
245                 contacts_svc_iter_remove(iter);
246
247                 if(existingAddedContacts)
248                         callbacks->onContactEventAdded(addedContacts);
249
250                 if(existingUpdatedContacts)
251                         callbacks->onContactEventUpdated(updatedContacts);
252
253                 if(existingRemovedContacts)
254                         callbacks->onContactEventRemoved(removedContactIds);
255         }
256
257         m_latestVersion = get_contact_version();
258 }
259
260 void ContactListenerManager::registerContactSvcChangedCallbacks()
261 {
262         int errorCode = 0;
263
264         if(m_callbackRegistered)
265         {
266                 LogWarning("Callback already registered.");
267                 return;
268         }
269
270         m_latestVersion = get_contact_version();
271
272         errorCode = contacts_svc_subscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE,
273                         contactsSvcEventCallback, reinterpret_cast<void *>(this));
274         if(errorCode != CTS_SUCCESS)
275         {
276                 LogWarning("contacts_svc_subscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE) returns Error (error");
277                 ThrowMsg(InvalidArgumentException, "Error while registering listener to contacts-service");
278         }
279
280         errorCode = contacts_svc_subscribe_change(CTS_SUBSCRIBE_ADDRESSBOOK_CHANGE,
281                         refresh_addressbook_list, reinterpret_cast<void *>(this));
282         if(errorCode != CTS_SUCCESS)
283         {
284                 LogWarning("contacts_svc_subscribe_change(CTS_SUBSCRIBE_ADDRESSBOOK_CHANGE) returns Error (error");
285                 ThrowMsg(InvalidArgumentException, "Error while registering listener to contacts-service");
286         }
287
288         m_callbackRegistered = true;
289 }
290
291 void ContactListenerManager::unregisterContactSvcChangedCallbacks()
292 {
293         int errorCode = 0;
294
295         if(!m_callbackRegistered)
296         {
297                 LogWarning("Callback already unregistered.");
298                 return;
299         }
300
301         m_latestVersion = 0;
302
303         errorCode = contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE,
304                         contactsSvcEventCallback);
305         if(errorCode != CTS_SUCCESS)
306         {
307                 LogWarning("contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE) returns Error (error");
308                 ThrowMsg(InvalidArgumentException, "Error while unregistering listener to contacts-service");
309         }
310
311         errorCode = contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_ADDRESSBOOK_CHANGE,
312                         refresh_addressbook_list);
313         if(errorCode != CTS_SUCCESS)
314         {
315                 LogWarning("contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_ADDRESSBOOK_CHANGE) returns Error (error");
316                 ThrowMsg(InvalidArgumentException, "Error while unregistering listener to contacts-service");
317         }
318
319         m_callbackRegistered = false;
320 }
321
322 IContactEventCallbacks* ContactListenerManager::getContactEventCallbacks(int id)
323 {
324         if(m_callbacks.find(id) == m_callbacks.end())
325                 return NULL;
326
327         return m_callbacks[id];
328 }
329
330 } // Application
331 } // Platform
332 } // TizenApis