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