Update change log and spec for wrt-plugins-tizen_0.4.50
[framework/web/wrt-plugins-tizen.git] / src / Callhistory / CallHistory.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18
19 #include "CallHistory.h"
20
21 #include <vector>
22 #include <string>
23 #include <sstream>
24 #include <Commons/Exception.h>
25 #include <CommonsJavaScript/JSCallbackManager.h>
26 #include <dpl/shared_ptr.h>
27 #include <Logger.h>
28
29 #include <IFilter.h>
30 #include <IFilterVisitor.h>
31 #include "CallHistoryDefine.h"
32
33 #include "CallHistoryFilter.h"
34
35 using namespace DeviceAPI::Tizen;
36 using namespace WrtDeviceApis;
37 using namespace WrtDeviceApis::Commons;
38 using namespace WrtDeviceApis::CommonsJavaScript;
39
40
41 namespace DeviceAPI {
42 namespace CallHistory {
43
44 std::vector<CallHistory::WatcherPtr> CallHistory::m_watchers;
45
46 CallHistory::CallHistory()
47 {
48         LoggerD("Enter ");
49         if (contacts_connect2() == CONTACTS_ERROR_NONE) {
50                 LoggerD("Successful to connect Call history DB ");
51         } else {
52                 LoggerD("Failed to connect Call history DB ");
53         }
54
55         EventCallHistoryPtr event(new EventCallHistory());
56         event->setCmdType(EventCallHistory::CONNECT);
57         event->setForSynchronousCall();
58         EventRequestReceiver<EventCallHistory>::PostRequest(event);
59 }
60
61 CallHistory::~CallHistory()
62 {
63         LoggerD("Enter ");
64
65         if (contacts_disconnect2()  == CONTACTS_ERROR_NONE) {
66                 LoggerD("Successful to disconnect Call history DB ");
67         } else {
68                 LoggerD("Failed to disconnect Call history DB ");
69         }
70
71         int ret = CONTACTS_ERROR_NONE;
72         std::vector<CallHistory::WatcherPtr>::iterator it = CallHistory::m_watchers.begin();
73
74         if (m_watchers.size() > 0) {
75                 for (;it < CallHistory::m_watchers.end();) {
76                         ret = contacts_db_remove_changed_cb_with_info(_contacts_phone_log._uri, callhistoryListenerCB, it->Get());
77
78                         if (ret != CONTACTS_ERROR_NONE) {
79                                 LoggerD("Failed removing listener");
80                         }
81
82                         it = CallHistory::m_watchers.erase(it);
83                 }
84         }
85
86         EventCallHistoryPtr event(new EventCallHistory());
87         event->setCmdType(EventCallHistory::DISCONNECT);
88         event->setForSynchronousCall();
89         EventRequestReceiver<EventCallHistory>::PostRequest(event);
90 }
91
92 void CallHistory::callhistoryListenerCB(const char* view_uri, char *changes, void* user_data)
93 {
94         
95         if (user_data != NULL) {
96                 ((CallHistory::Watcher*)user_data)->ListenerCB(changes);
97         }
98 }
99
100 void CallHistory::removeBatchCB(int error, void *user_data)
101 {
102         LoggerD("enter");
103         if (user_data != NULL) {
104                 CallHistory* chManager = (CallHistory *)((EventCallHistoryPtrs<EventRemoveBatch> *)user_data)->getThisPtr();
105
106                 if (chManager) {
107                         EventRemoveBatchPtr event = ((EventCallHistoryPtrs<EventRemoveBatch> *)user_data)->getEventPtrs();
108                         chManager->callRemoveBatchEvent(error, event);
109                 }
110         }
111         return;
112 }
113
114 void CallHistory::removeAllCB(int error, void *user_data)
115 {
116         LoggerD("enter");
117         if (user_data != NULL) {
118                 CallHistory* chManager = (CallHistory *)((EventCallHistoryPtrs<EventRemoveAll> *)user_data)->getThisPtr();
119
120                 if (chManager) {
121                         EventRemoveAllPtr event = ((EventCallHistoryPtrs<EventRemoveAll> *)user_data)->getEventPtrs();
122                         chManager->callRemoveAllEvent(error, event);
123                 }
124         }
125         return;
126 }
127
128 bool CallHistory::convertCallHistory(callhistory_query_s *query_log, CallHistoryEntryListPtr &callEntries)
129 {
130         if (query_log == NULL || callEntries == NULL)
131                 return false;
132
133         CallHistoryEntryPropertiesPtr callHistoryItem(new CallHistoryEntryProperties());
134         StringArrayPtr stringArray(new StringArray());
135         RemotePartyPtr remoteParty(new RemoteParty());
136         RemotePartyListPtr remotePartyList(new RemotePartyList());
137
138         std::string callType("");
139         std::string tags("");
140         std::string direction("");
141         std::string number("");
142
143         if (query_log->phone_number != NULL) {
144                 number.append(query_log->phone_number);
145         }
146
147         switch(query_log->calllog_type) {
148         case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
149                 callType.append(STR_TIZEN_TEL);
150                 tags.append(STR_CALL_VOICE);
151                 direction.append(STR_RECEIVED);
152                 break;
153         case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
154                 callType.append(STR_TIZEN_TEL);
155                 tags.append(STR_CALL_VOICE);
156                 direction.append(STR_DIALED);
157                 break;
158         case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN:
159                 callType.append(STR_TIZEN_TEL);
160                 tags.append(STR_CALL_VOICE);
161                 direction.append(STR_MISSED);
162                 break;
163         case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN:
164                 callType.append(STR_TIZEN_TEL);
165                 tags.append(STR_CALL_VOICE);
166                 direction.append(STR_MISSED_NEW);
167                 break;
168         case CONTACTS_PLOG_TYPE_VOICE_REJECT:
169                 callType.append(STR_TIZEN_TEL);
170                 tags.append(STR_CALL_VOICE);
171                 direction.append(STR_REJECTED);
172                 break;
173         case CONTACTS_PLOG_TYPE_VOICE_BLOCKED:
174                 callType.append(STR_TIZEN_TEL);
175                 tags.append(STR_CALL_VOICE);
176                 direction.append(STR_BLOCKED);
177                 break;
178         case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
179                 callType.append(STR_TIZEN_TEL);
180                 tags.append(STR_CALL_VIDEO);
181                 direction.append(STR_RECEIVED);
182                 break;
183         case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
184                 callType.append(STR_TIZEN_TEL);
185                 tags.append(STR_CALL_VIDEO);
186                 direction.append(STR_DIALED);
187                 break;
188         case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN:
189                 callType.append(STR_TIZEN_TEL);
190                 tags.append(STR_CALL_VIDEO);
191                 direction.append(STR_MISSED);
192                 break;
193         case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN:
194                 callType.append(STR_TIZEN_TEL);
195                 tags.append(STR_CALL_VIDEO);
196                 direction.append(STR_MISSED_NEW);
197                 break;
198         case CONTACTS_PLOG_TYPE_VIDEO_REJECT:
199                 callType.append(STR_TIZEN_TEL);
200                 tags.append(STR_CALL_VIDEO);
201                 direction.append(STR_REJECTED);
202                 break;
203         case CONTACTS_PLOG_TYPE_VIDEO_BLOCKED:
204                 callType.append(STR_TIZEN_TEL);
205                 tags.append(STR_CALL_VIDEO);
206                 direction.append(STR_BLOCKED);
207                 break;
208         default:
209                 return false;
210         }
211
212         callHistoryItem->setEntryId(query_log->calllog_db_id);
213         callHistoryItem->setCallType(callType);
214         stringArray->push_back(tags);
215         callHistoryItem->setTags(stringArray);
216
217         remoteParty->setRemoteParty(number);
218         std::stringstream personIdStream;
219         personIdStream << query_log->person_db_id;
220         remoteParty->setPersonId(personIdStream.str());
221
222         remotePartyList->push_back(remoteParty);
223         callHistoryItem->setRemoteParties(remotePartyList);
224
225         callHistoryItem->setStartTime(query_log->timestamp);
226         callHistoryItem->setDuration((unsigned long)(query_log->duration_sec));
227         callHistoryItem->setDirection(direction);
228
229         callEntries->insert(callEntries->end(), callHistoryItem);
230
231         return true;
232 }
233
234 void CallHistory::find(const EventFindCallHistoryPtr& event)
235 {
236         EventRequestReceiver<EventFindCallHistory>::PostRequest(event);
237 }
238
239 bool CallHistory::remove(const unsigned long entryId)
240 {
241         try {
242                 int ret = contacts_db_delete_record(_contacts_phone_log._uri, (int)entryId);
243
244                 if (ret == CONTACTS_ERROR_NONE) {
245                         return true;
246                 } else {
247                         return false;
248                 }
249         } catch (const Commons::PlatformException& ex) {
250                 ThrowMsg(Commons::PlatformException, ex.GetMessage());
251         }
252 }
253
254 void CallHistory::removeBatch(const EventRemoveBatchPtr& event)
255 {
256         EventRequestReceiver<EventRemoveBatch>::PostRequest(event);
257 }
258
259 void CallHistory::removeAll(const EventRemoveAllPtr& event)
260 {
261         EventRequestReceiver<EventRemoveAll>::PostRequest(event);
262 }
263
264 long CallHistory::addListener(const EventCallHistoryListenerEmitterPtr& emitter)
265 {
266         int ret =0;
267
268         if (CallHistory::m_watchers.size() == 0) {
269                 WatcherPtr watcher(new Watcher(0, emitter));
270                 ret = contacts_db_add_changed_cb_with_info(_contacts_phone_log._uri, callhistoryListenerCB, watcher.Get());
271
272                 watcher->setHandle(static_cast<long>(emitter->getId()));
273                 CallHistory::m_watchers.push_back(watcher);
274                 return watcher->getHandle();
275         } else {
276                 return 0;
277         }
278 }
279
280 void CallHistory::removeListener(const long id)
281 {
282         std::vector<CallHistory::WatcherPtr>::iterator it = CallHistory::m_watchers.begin();
283         bool flag = false;
284         int ret = CONTACTS_ERROR_NONE;
285
286         for (;it < CallHistory::m_watchers.end();) {
287
288                 if (id == (*it)->getHandle()) {
289                         flag = true;
290                         ret = contacts_db_remove_changed_cb_with_info(_contacts_phone_log._uri, callhistoryListenerCB, it->Get());
291
292                         if (ret != CONTACTS_ERROR_NONE) {
293                                 LoggerD("Failed removing listener");
294                         }
295
296                         it = CallHistory::m_watchers.erase(it);
297                         continue;
298                 }
299                 ++it;
300         }
301
302         if (!flag) {
303                 ThrowMsg(Commons::InvalidArgumentException, "Invalid values");
304         }
305 }
306
307 bool CallHistory::parseRecord(contacts_list_h *recordList, CallHistoryEntryListPtr &callEntries)
308 {
309         int ret = CONTACTS_ERROR_NONE;
310         unsigned int total = 0;
311         contacts_record_h record = NULL;
312         callhistory_query_s query_data;
313         int logType = 0;
314         int time = 0;
315         unsigned int i =0;
316
317         contacts_list_get_count(*recordList, &total);
318
319         for (i = 0; i < total; i++) {
320                 ret = contacts_list_get_current_record_p(*recordList, &record);
321
322                 if (record == NULL) {
323                         ret = contacts_list_next(*recordList);
324                         if (ret != CONTACTS_ERROR_NONE && ret != CONTACTS_ERROR_NO_DATA) {
325                                 LoggerD("Failed callhistory parser");
326                                 return false;
327                         } else {
328                                 continue;
329                         }
330                 }
331
332                 memset(&query_data, 0x00, sizeof(callhistory_query_s));
333                 int validPersonId = 0;
334
335                 if (ret == CONTACTS_ERROR_NONE) {
336                         contacts_record_get_int(record, _contacts_phone_log.id, &(query_data.calllog_db_id));
337                         contacts_record_get_int(record, _contacts_phone_log.log_type , &logType);
338                         contacts_record_get_int(record, _contacts_phone_log.person_id, &(query_data.person_db_id));
339                         contacts_record_get_str_p(record, _contacts_phone_log.address, &(query_data.phone_number));
340
341                         validPersonId = 0;
342                         validPersonId = updateValidPersonId(query_data.phone_number);
343                         query_data.person_db_id = validPersonId;
344
345                         contacts_record_get_int(record, _contacts_phone_log.log_time, &time);
346                         contacts_record_get_int(record, _contacts_phone_log.extra_data1, &(query_data.duration_sec));
347                         query_data.calllog_type = static_cast<contacts_phone_log_type_e>(logType);
348                         query_data.timestamp = static_cast<time_t>(time);
349                         convertCallHistory(&query_data, callEntries);
350                 }
351
352                 ret = contacts_list_next(*recordList);
353                 if (ret != CONTACTS_ERROR_NONE && ret != CONTACTS_ERROR_NO_DATA) {
354                         LoggerD("Failed callhistory parser");
355                         return false;
356                 }
357         }
358
359         return true;
360
361 }
362
363 int CallHistory::updateValidPersonId(char* phoneNum)
364 {
365         contacts_query_h query = NULL;
366         contacts_filter_h filter = NULL;
367         contacts_list_h recordList = NULL;
368         int ret = CONTACTS_ERROR_NONE;
369
370         contacts_query_create(_contacts_person_phone_log._uri, &query);
371         contacts_filter_create(_contacts_person_phone_log._uri, &filter);
372         contacts_filter_add_str(filter, _contacts_person_phone_log.address, CONTACTS_MATCH_EXACTLY, phoneNum);
373
374         contacts_query_set_filter(query, filter);
375
376         ret = contacts_db_get_records_with_query(query, 0, 1, &recordList);
377         if (ret != CONTACTS_ERROR_NONE) {
378                 contacts_list_destroy(recordList, true);
379                 contacts_query_destroy(query);
380                 contacts_filter_destroy(filter);
381                 LoggerD("Invalid callhistory query [" << ret << "]");
382                 return 0;
383         }
384
385         contacts_record_h record = NULL;
386         int validPersonId = 0;
387
388         ret = contacts_list_get_current_record_p(recordList, &record);
389         if (ret == CONTACTS_ERROR_NONE) {
390                 contacts_record_get_int(record, _contacts_person_phone_log.person_id, &validPersonId);
391         }
392
393         contacts_list_destroy(recordList, true);
394         contacts_query_destroy(query);
395         contacts_filter_destroy(filter);
396
397         return validPersonId;
398
399 }
400
401
402 unsigned int CallHistory::convertAttrName(std::string &name)
403 {
404         std::string attrName("");
405         if (name.compare(STR_RP_REMOTEPARTY) == 0) {
406                 return _contacts_phone_log.address;
407         } else if (name.compare(STR_START_TIME) == 0) {
408                 return _contacts_phone_log.log_time;
409         } else if (name.compare(STR_DURATION) == 0) {
410                 return _contacts_phone_log.extra_data1;
411         } else if (name.compare(STR_DIRECTION) == 0) {
412                 return _contacts_phone_log.log_type;
413         } else if (name.compare(STR_ENTRY_ID) == 0) {
414                 return _contacts_phone_log.id;
415         } else {
416                 return 0;
417         }
418 }
419
420 void CallHistory::OnRequestReceived(const EventCallHistoryPtr& event)
421 {
422         try {
423                 if (event->getCmdType() == EventCallHistory::CONNECT) {
424                         if (contacts_connect2() == CONTACTS_ERROR_NONE) {
425                                 LoggerD("Successful to connect Call history DB by sub thread");
426                         } else {
427                                 LoggerD("Failed to connect Call history DB by sub thread");
428                         }
429                 } else if (event->getCmdType() == EventCallHistory::DISCONNECT) {
430                         if (contacts_disconnect2()  == CONTACTS_ERROR_NONE) {
431                                 LoggerD("Successful to disconnect Call history DB by sub thread");
432                         } else {
433                                 LoggerD("Failed to disconnect Call history DB by sub thread");
434                         }
435                 }
436         } catch (const Commons::PlatformException& ex) {
437                 LoggerE("Exception: " << ex.GetMessage());
438                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
439         }
440 }
441
442 void CallHistory::OnRequestReceived(const EventFindCallHistoryPtr& event)
443 {
444         try {
445                 LoggerD("enter");
446                 CallHistoryEntryListPtr callHistoryListPtr(new CallHistoryEntryList());
447                 int ret = CONTACTS_ERROR_NONE;
448
449                 contacts_query_h query = NULL;
450                 contacts_filter_h filter = NULL;
451                 contacts_list_h recordList = NULL;
452                 bool isAscending = false;
453                 int limit = 0;
454                 int offset = 0;
455
456                 contacts_query_create(_contacts_phone_log._uri, &query);
457                 contacts_filter_create(_contacts_phone_log._uri, &filter);
458
459                 CallHistoryFilterPtr filtering(new CallHistoryFilter(filter));
460                 IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<IFilterVisitor>(filtering);
461
462                 if (event->getFilterIsSet()) {
463                         FilterPtr filterPtr = event->getFilter();
464                         filterPtr->travel(filterTraversal, 0);
465
466                         contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
467                         contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
468                 } else {
469                         contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
470                 }
471                 contacts_query_set_filter(query, filter);
472
473                 if (event->getSortModesIsSet()) {
474                         if (event->getSortMode()->getOrder() == DeviceAPI::Tizen::ASCENDING_SORT_ORDER) {
475                                 isAscending = true;
476                         } else {
477                                 isAscending = false;
478                         }
479                         std::string attriName(event->getSortMode()->getAttributeName());
480                         ret = contacts_query_set_sort(query, convertAttrName(attriName), isAscending);
481
482                 } else {
483                         ret = contacts_query_set_sort(query, _contacts_phone_log.id, isAscending);
484                 }
485
486                 if (ret != CONTACTS_ERROR_NONE) {
487                         LoggerD("callhistory invalid query statement");
488                 }
489
490
491                 if (event->getLimitIsSet()) {
492                         limit = static_cast<int>(event->getLimit());
493                 }
494
495                 if (event->getOffsetIsSet()) {
496                         offset = static_cast<int>(event->getOffset());
497                 }
498
499                 ret = contacts_db_get_records_with_query(query, offset, limit, &recordList);
500
501                 if (ret != CONTACTS_ERROR_NONE) {
502                         LoggerD("Invalid query statement");
503                 }
504
505                 if (parseRecord(&recordList, callHistoryListPtr)) {
506                         event->setResult(callHistoryListPtr);
507                 }
508
509                 contacts_list_destroy(recordList, true);
510                 contacts_query_destroy(query);
511                 contacts_filter_destroy(filter);
512         } catch (const Commons::PlatformException& ex) {
513                 LoggerE("Exception: " << ex.GetMessage());
514                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
515         }
516 }
517
518 void CallHistory::OnRequestReceived(const EventRemoveBatchPtr& event)
519 {
520         int* list = NULL;
521
522         try {
523                 std::vector<unsigned long> entryIds = event->getEntryIds();
524                 unsigned int cnt = 0;
525                 int ret = CONTACTS_ERROR_NONE;
526                 list = new int[entryIds.size()];
527
528                 for (cnt = 0; cnt < entryIds.size(); cnt++) {
529                         list[cnt] = static_cast<int>(entryIds[cnt]);
530                 }
531
532                 if (entryIds.size() > 0) {
533                         EventRemoveBatchDataPtr eventData( new EventCallHistoryPtrs<EventRemoveBatch>(event, this));
534
535                         JSCallbackManagerPtr data = DPL::DynamicPointerCast<JSCallbackManager>(event->getPrivateData());
536                         if (data != NULL) {
537                                 if (data->getOnSuccess() != NULL) {
538                                         ret = contacts_db_delete_records_async(_contacts_phone_log._uri, list, entryIds.size(), removeBatchCB, eventData.Get());
539                                         if (ret == CONTACTS_ERROR_NONE) {
540                                                 m_removeBatchEvent.push_back(eventData);
541                                                 event->switchToManualAnswer();
542                                         } else {
543                                                 LoggerD("Failed callhistory remove Batch [" << ret << "]");
544                                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
545                                         }
546                                 } else {
547                                         ret = contacts_db_delete_records(_contacts_phone_log._uri, list, entryIds.size());
548                                         if (ret != CONTACTS_ERROR_NONE) {
549                                                 LoggerD("Failed callhistory remove Batch [" << ret << "]");
550                                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
551                                         }
552                                 }
553                         } else {
554                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
555                         }
556                 }
557
558         } catch (const Commons::PlatformException& ex) {
559                 LoggerE("Exception: " << ex.GetMessage());
560                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
561         }
562
563         if (list != NULL) {
564                 delete[] list;
565                 list = NULL;
566         }
567 }
568
569 void CallHistory::OnRequestReceived(const EventRemoveAllPtr& event)
570 {
571         int* list = NULL;
572
573         try {
574                 int ret = CONTACTS_ERROR_NONE;
575                 contacts_list_h record_list = NULL;
576                 contacts_record_h record = NULL;
577                 unsigned int total = 0;
578                 unsigned int cnt = 0;
579                 int value = 0;
580
581                 ret = contacts_db_get_all_records(_contacts_phone_log._uri, 0, 0, &record_list);
582
583                 if (record_list == NULL) {
584                         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
585                         return;
586                 }
587
588                 contacts_list_get_count(record_list, &total);
589
590                 list = new int[total];
591                 for (unsigned int i = 0; i < total; i++) {
592                         ret = contacts_list_get_current_record_p(record_list, &record);
593
594                         if (record == NULL) {
595                                 ret = contacts_list_next(record_list);
596                                 if ( !(ret==CONTACTS_ERROR_NONE || ret==CONTACTS_ERROR_NO_DATA) ){
597                                         LoggerD("Failed callhistory remove all [" << ret << "]");
598                                         event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
599                                 }
600                                 continue;
601                         }
602
603                         if (ret == CONTACTS_ERROR_NONE) {
604                                 ret = contacts_record_get_int(record, _contacts_phone_log.id , &value);
605                                 if (ret == CONTACTS_ERROR_NONE) {
606                                         list[cnt] = value;
607                                         cnt++;
608                                 }
609                         }
610                         value = 0;
611                         ret = contacts_list_next(record_list);
612                         if ( !(ret==CONTACTS_ERROR_NONE || ret==CONTACTS_ERROR_NO_DATA) ){
613                                 LoggerD("Failed callhistory remove all [" << ret << "]");
614                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
615                         }
616                 }
617
618                 if (cnt > 0) {
619                         EventRemoveAllDataPtr eventData( new EventCallHistoryPtrs<EventRemoveAll>(event, this));
620
621                         JSCallbackManagerPtr data = DPL::DynamicPointerCast<JSCallbackManager>(event->getPrivateData());
622                         if (data != NULL) {
623                                 if (data->getOnSuccess() != NULL) {
624                                         ret = contacts_db_delete_records_async(_contacts_phone_log._uri, list, cnt, removeAllCB, eventData.Get());
625                                         if (ret == CONTACTS_ERROR_NONE) {
626                                                 m_removeAllEvent.push_back(eventData);
627                                                 event->switchToManualAnswer();
628                                         } else {
629                                                 LoggerD("Failed callhistory remove all [" << ret << "]");
630                                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
631                                         }
632                                 } else {
633                                         ret = contacts_db_delete_records(_contacts_phone_log._uri, list, cnt);
634                                         if (ret != CONTACTS_ERROR_NONE) {
635                                                 LoggerD("Failed callhistory remove all [" << ret << "]");
636                                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
637                                         }
638                                 }
639                         }
640                 }
641
642                 contacts_list_destroy(record_list, true);
643         } catch (const Commons::PlatformException& ex) {
644                 LoggerE("Exception: " << ex.GetMessage());
645                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
646         }
647
648         if (list != NULL) {
649                 delete[] list;
650                 list = NULL;
651         }
652 }
653
654 void CallHistory::callRemoveBatchEvent(int error, const EventRemoveBatchPtr &event)
655 {
656         if (error != CONTACTS_ERROR_NONE) {
657                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
658         }
659
660         EventRequestReceiver<EventRemoveBatch>::ManualAnswer(event);
661
662         std::vector<EventRemoveBatchDataPtr>::iterator it;
663         for (it = m_removeBatchEvent.begin(); it != m_removeBatchEvent.end(); ++it) {
664                 if ((*it)->getEventPtrs() == event) {
665                         m_removeBatchEvent.erase(it);
666                         break;
667                 }
668         }
669 }
670
671 void CallHistory::callRemoveAllEvent(int error, const EventRemoveAllPtr &event)
672 {
673         if (error != CONTACTS_ERROR_NONE) {
674                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
675         }
676
677         EventRequestReceiver<EventRemoveAll>::ManualAnswer(event);
678
679         std::vector<EventRemoveAllDataPtr>::iterator it;
680         for (it = m_removeAllEvent.begin(); it != m_removeAllEvent.end(); ++it) {
681                 if ((*it)->getEventPtrs() == event) {
682                         m_removeAllEvent.erase(it);
683                         break;
684                 }
685         }
686 }
687
688 CallHistory::Watcher::Watcher(long handle, const EventCallHistoryListenerEmitterPtr& emitter) :
689                         m_handle(handle),
690                         m_emitter(emitter),
691                         m_currentLogId(0)
692 {
693         m_missedCallList = MissedCallListPtr(new MissedCallList());
694         if (contacts_connect2() == CONTACTS_ERROR_NONE) {
695                 LoggerD("Successful to connect Call history DB ");
696         } else {
697                 LoggerD("Failed to connect Call history DB ");
698         }
699 }
700
701 CallHistory::Watcher::~Watcher()
702 {
703         if (contacts_disconnect2()  == CONTACTS_ERROR_NONE) {
704                 LoggerD("Successful to disconnect Call history DB ");
705         } else {
706                 LoggerD("Failed to disconnect Call history DB ");
707         }
708 }
709
710 void CallHistory::Watcher::stateHasChanged(CallHistoryEntryListPtr &entryList, EventCallHistoryListener::ResultStates state)
711 {
712         if (entryList == NULL)
713                 return;
714
715         LoggerD("enter");
716
717         EventCallHistoryListenerPtr event(new EventCallHistoryListener());
718         event->setResultState(state);
719         event->setResult(entryList);
720         m_emitter->emit(event);
721 }
722
723 void CallHistory::Watcher::stateHasRemoved(StringArrayPtr &entryList, EventCallHistoryListener::ResultStates state)
724 {
725         if (entryList == NULL)
726                 return;
727
728         LoggerD("enter");
729
730         EventCallHistoryListenerPtr event(new EventCallHistoryListener());
731         event->setResultState(state);
732         event->setRemoveResult(entryList);
733         m_emitter->emit(event);
734 }
735
736
737 bool CallHistory::Watcher::parseRecord(contacts_list_h *recordList, CallHistoryEntryListPtr &entryList)
738 {
739         CallHistory* callHistory = (CallHistory *) this;
740         if (callHistory != NULL) {
741                 return callHistory->parseRecord(recordList, entryList);
742         }
743         return false;
744 }
745
746 bool CallHistory::Watcher::parseRemoveRecord(char* record, StringArrayPtr &removeRecords)
747 {
748         std::string recordStr(record);
749         removeRecords->push_back(recordStr);
750
751         return true;
752 }
753
754 void CallHistory::Watcher::ListenerCB(char* changes)
755 {
756         LoggerD("enter");
757
758         char seps[] = ",:";
759         char* tokenType = NULL;
760         char* tokenId = NULL;
761         int changeType = 0;
762         int changeId = 0;
763
764         CallHistoryEntryListPtr callHistoryListPtr(new CallHistoryEntryList());
765         StringArrayPtr RemoveListPtr(new StringArray());
766
767         tokenType = strtok( changes, seps );
768         while( tokenType != NULL )
769         {
770                 tokenId = strtok( NULL, seps );
771
772                 if(tokenType!=NULL)
773                         changeType = atoi((const char*)tokenType);
774                 if(tokenId != NULL)
775                         changeId = atoi((const char*)tokenId);
776
777
778                 contacts_query_h query = NULL;
779                 contacts_filter_h filter = NULL;
780                 contacts_list_h recordList = NULL;
781                 int ret = CONTACTS_ERROR_NONE;
782
783                 contacts_query_create(_contacts_phone_log._uri, &query);
784                 contacts_filter_create(_contacts_phone_log._uri, &filter);
785                 contacts_filter_add_int(filter, _contacts_phone_log.id, CONTACTS_MATCH_EQUAL, changeId  );
786
787                 contacts_query_set_filter(query, filter);
788
789                 ret = contacts_query_set_sort(query, _contacts_phone_log.id, false);
790                 if (ret != CONTACTS_ERROR_NONE) {
791                         LoggerD("Invalid callhistory query [" << ret << "]");
792                 }
793
794                 ret = contacts_db_get_records_with_query(query, 0, 1, &recordList);
795                 if (ret != CONTACTS_ERROR_NONE) {
796                         contacts_list_destroy(recordList, true);
797                         contacts_query_destroy(query);
798                         contacts_filter_destroy(filter);
799                         LoggerD("Invalid callhistory query [" << ret << "]");
800                         return;
801                 }
802
803                 if((changeType == CONTACTS_CHANGE_INSERTED)||(changeType == CONTACTS_CHANGE_UPDATED)){
804                         if (parseRecord(&recordList, callHistoryListPtr)) {
805                                 if (callHistoryListPtr->size() > 0) {
806                                         setCurrentLogId((*callHistoryListPtr)[0]->getEntryId());
807                                 }
808                         }
809                 }else if(changeType == CONTACTS_CHANGE_DELETED){
810                         parseRemoveRecord(tokenId, RemoveListPtr);
811                 }
812
813                 contacts_list_destroy(recordList, true);
814                 contacts_query_destroy(query);
815                 contacts_filter_destroy(filter);
816
817                 tokenType = strtok( NULL, seps );
818         }
819
820
821         if((changeType == CONTACTS_CHANGE_INSERTED)||(changeType == CONTACTS_CHANGE_UPDATED)){
822                 if (callHistoryListPtr->size() > 0) {
823                         setCurrentLogId((*callHistoryListPtr)[0]->getEntryId());
824
825                         if(changeType == CONTACTS_CHANGE_INSERTED){
826                                 stateHasChanged(callHistoryListPtr, EventCallHistoryListener::ADDED);
827                         }else if(changeType == CONTACTS_CHANGE_UPDATED){
828                                 stateHasChanged(callHistoryListPtr, EventCallHistoryListener::CHANGED);
829                         }
830
831                 }
832         }else if(changeType == CONTACTS_CHANGE_DELETED){
833                 stateHasRemoved(RemoveListPtr, EventCallHistoryListener::REMOVED);
834         }
835
836 }
837
838 }
839 }
840