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