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