2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "CallHistory.h"
25 #include <Commons/Exception.h>
26 #include <CommonsJavaScript/JSCallbackManager.h>
27 #include <dpl/shared_ptr.h>
31 #include <IFilterVisitor.h>
32 #include "CallHistoryDefine.h"
34 #include "CallHistoryFilter.h"
36 using namespace DeviceAPI::Tizen;
37 using namespace WrtDeviceApis;
38 using namespace WrtDeviceApis::Commons;
39 using namespace WrtDeviceApis::CommonsJavaScript;
43 namespace CallHistory {
45 std::vector<CallHistory::WatcherPtr> CallHistory::m_watchers;
47 CallHistory::CallHistory()
50 if (contacts_connect2() == CONTACTS_ERROR_NONE) {
51 LoggerD("Successful to connect Call history DB ");
53 LoggerD("Failed to connect Call history DB ");
56 EventCallHistoryPtr event(new EventCallHistory());
57 event->setCmdType(EventCallHistory::CONNECT);
58 event->setForSynchronousCall();
59 EventRequestReceiver<EventCallHistory>::PostRequest(event);
62 CallHistory::~CallHistory()
66 if (contacts_disconnect2() == CONTACTS_ERROR_NONE) {
67 LoggerD("Successful to disconnect Call history DB ");
69 LoggerD("Failed to disconnect Call history DB ");
72 int ret = CONTACTS_ERROR_NONE;
73 std::vector<CallHistory::WatcherPtr>::iterator it = CallHistory::m_watchers.begin();
75 if (m_watchers.size() > 0) {
76 for (;it < CallHistory::m_watchers.end();) {
77 //ret = contacts_db_remove_changed_cb(_contacts_phone_log._uri, callhistoryListenerCB, it->Get());
78 ret = contacts_db_remove_changed_cb_with_info(_contacts_phone_log._uri, callhistoryListenerCB, it->Get());
80 if (ret != CONTACTS_ERROR_NONE) {
81 LoggerD("callhistory remove listener error [" << ret << "]");
84 it = CallHistory::m_watchers.erase(it);
86 LoggerD("CallHistory Watcher is removed. (" << CallHistory::m_watchers.size() << ")");
89 EventCallHistoryPtr event(new EventCallHistory());
90 event->setCmdType(EventCallHistory::DISCONNECT);
91 event->setForSynchronousCall();
92 EventRequestReceiver<EventCallHistory>::PostRequest(event);
95 void CallHistory::callhistoryListenerCB(const char* view_uri, char *changes, void* user_data)
98 if (user_data != NULL) {
99 ((CallHistory::Watcher*)user_data)->ListenerCB(changes);
103 void CallHistory::removeBatchCB(int error, void *user_data)
106 if (user_data != NULL) {
107 CallHistory* chManager = (CallHistory *)((EventCallHistoryPtrs<EventRemoveBatch> *)user_data)->getThisPtr();
110 EventRemoveBatchPtr event = ((EventCallHistoryPtrs<EventRemoveBatch> *)user_data)->getEventPtrs();
111 chManager->callRemoveBatchEvent(error, event);
117 void CallHistory::removeAllCB(int error, void *user_data)
120 if (user_data != NULL) {
121 CallHistory* chManager = (CallHistory *)((EventCallHistoryPtrs<EventRemoveAll> *)user_data)->getThisPtr();
124 EventRemoveAllPtr event = ((EventCallHistoryPtrs<EventRemoveAll> *)user_data)->getEventPtrs();
125 chManager->callRemoveAllEvent(error, event);
131 bool CallHistory::convertCallHistory(callhistory_query_s *query_log, CallHistoryEntryListPtr &callEntries)
133 if (query_log == NULL || callEntries == NULL)
136 CallHistoryEntryPropertiesPtr callHistoryItem(new CallHistoryEntryProperties());
137 StringArrayPtr stringArray(new StringArray());
138 RemotePartyPtr remoteParty(new RemoteParty());
139 RemotePartyListPtr remotePartyList(new RemotePartyList());
141 std::string callType("");
142 std::string tags("");
143 std::string direction("");
144 std::string number("");
146 if (query_log->phone_number != NULL) {
147 number.append(query_log->phone_number);
150 switch(query_log->calllog_type) {
151 case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
152 callType.append(STR_TIZEN_TEL);
153 tags.append(STR_CALL_VOICE);
154 direction.append(STR_RECEIVED);
156 case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
157 callType.append(STR_TIZEN_TEL);
158 tags.append(STR_CALL_VOICE);
159 direction.append(STR_DIALED);
161 case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN:
162 callType.append(STR_TIZEN_TEL);
163 tags.append(STR_CALL_VOICE);
164 direction.append(STR_MISSED);
166 case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN:
167 callType.append(STR_TIZEN_TEL);
168 tags.append(STR_CALL_VOICE);
169 direction.append(STR_MISSED_NEW);
171 case CONTACTS_PLOG_TYPE_VOICE_REJECT:
172 callType.append(STR_TIZEN_TEL);
173 tags.append(STR_CALL_VOICE);
174 direction.append(STR_REJECTED);
176 case CONTACTS_PLOG_TYPE_VOICE_BLOCKED:
177 callType.append(STR_TIZEN_TEL);
178 tags.append(STR_CALL_VOICE);
179 direction.append(STR_BLOCKED);
181 case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
182 callType.append(STR_TIZEN_TEL);
183 tags.append(STR_CALL_VIDEO);
184 direction.append(STR_RECEIVED);
186 case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
187 callType.append(STR_TIZEN_TEL);
188 tags.append(STR_CALL_VIDEO);
189 direction.append(STR_DIALED);
191 case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN:
192 callType.append(STR_TIZEN_TEL);
193 tags.append(STR_CALL_VIDEO);
194 direction.append(STR_MISSED);
196 case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN:
197 callType.append(STR_TIZEN_TEL);
198 tags.append(STR_CALL_VIDEO);
199 direction.append(STR_MISSED_NEW);
201 case CONTACTS_PLOG_TYPE_VIDEO_REJECT:
202 callType.append(STR_TIZEN_TEL);
203 tags.append(STR_CALL_VIDEO);
204 direction.append(STR_REJECTED);
206 case CONTACTS_PLOG_TYPE_VIDEO_BLOCKED:
207 callType.append(STR_TIZEN_TEL);
208 tags.append(STR_CALL_VIDEO);
209 direction.append(STR_BLOCKED);
215 callHistoryItem->setEntryId(query_log->calllog_db_id);
216 callHistoryItem->setCallType(callType);
217 stringArray->push_back(tags);
218 callHistoryItem->setTags(stringArray);
220 remoteParty->setRemoteParty(number);
221 std::stringstream personIdStream;
222 personIdStream << query_log->person_db_id;
223 remoteParty->setPersonId(personIdStream.str());
225 remotePartyList->push_back(remoteParty);
226 callHistoryItem->setRemoteParties(remotePartyList);
228 callHistoryItem->setStartTime(query_log->timestamp);
229 callHistoryItem->setDuration((unsigned long)(query_log->duration_sec));
230 callHistoryItem->setDirection(direction);
232 callEntries->insert(callEntries->end(), callHistoryItem);
237 void CallHistory::find(const EventFindCallHistoryPtr& event)
239 EventRequestReceiver<EventFindCallHistory>::PostRequest(event);
242 bool CallHistory::remove(const unsigned long entryId)
245 int ret = contacts_db_delete_record(_contacts_phone_log._uri, (int)entryId);
247 if (ret == CONTACTS_ERROR_NONE) {
252 } catch (const Commons::PlatformException& ex) {
253 ThrowMsg(Commons::PlatformException, ex.GetMessage());
257 void CallHistory::removeBatch(const EventRemoveBatchPtr& event)
259 EventRequestReceiver<EventRemoveBatch>::PostRequest(event);
262 void CallHistory::removeAll(const EventRemoveAllPtr& event)
264 EventRequestReceiver<EventRemoveAll>::PostRequest(event);
267 long CallHistory::addListener(const EventCallHistoryListenerEmitterPtr& emitter)
271 if (CallHistory::m_watchers.size() == 0) {
272 WatcherPtr watcher(new Watcher(0, emitter));
273 ret = contacts_db_add_changed_cb_with_info(_contacts_phone_log._uri, callhistoryListenerCB, watcher.Get());
275 watcher->setHandle(static_cast<long>(emitter->getId()));
276 CallHistory::m_watchers.push_back(watcher);
277 return watcher->getHandle();
283 void CallHistory::removeListener(const long id)
285 std::vector<CallHistory::WatcherPtr>::iterator it = CallHistory::m_watchers.begin();
287 int ret = CONTACTS_ERROR_NONE;
289 for (;it < CallHistory::m_watchers.end();) {
291 LoggerD("removeListener : id ["<<id<<"]");
292 LoggerD("removeListener : handle() ["<<(*it)->getHandle()<<"]");
294 if (id == (*it)->getHandle()) {
296 ret = contacts_db_remove_changed_cb_with_info(_contacts_phone_log._uri, callhistoryListenerCB, it->Get());
298 if (ret != CONTACTS_ERROR_NONE) {
299 LoggerD("callhistory remove listener error [" << ret << "]");
302 it = CallHistory::m_watchers.erase(it);
309 ThrowMsg(Commons::InvalidArgumentException, "Invalid values error : handle");
313 bool CallHistory::parseRecord(contacts_list_h *recordList, CallHistoryEntryListPtr &callEntries)
315 int ret = CONTACTS_ERROR_NONE;
316 unsigned int total = 0;
317 contacts_record_h record = NULL;
318 callhistory_query_s query_data;
322 contacts_list_get_count(*recordList, &total);
324 for (int i = 0; i < total; i++) {
325 ret = contacts_list_get_current_record_p(*recordList, &record);
327 if (record == NULL) {
328 ret = contacts_list_next(*recordList);
329 if (ret != CONTACTS_ERROR_NONE && ret != CONTACTS_ERROR_NO_DATA) {
330 LoggerD("callhistory parse error [" << ret << "]");
337 memset(&query_data, 0x00, sizeof(callhistory_query_s));
339 if (ret == CONTACTS_ERROR_NONE) {
340 contacts_record_get_int(record, _contacts_phone_log.id, &(query_data.calllog_db_id));
341 contacts_record_get_int(record, _contacts_phone_log.log_type , &logType);
342 contacts_record_get_int(record, _contacts_phone_log.person_id, &(query_data.person_db_id));
343 contacts_record_get_str_p(record, _contacts_phone_log.address, &(query_data.phone_number));
344 contacts_record_get_int(record, _contacts_phone_log.log_time, &time);
345 contacts_record_get_int(record, _contacts_phone_log.extra_data1, &(query_data.duration_sec));
346 query_data.calllog_type = static_cast<contacts_phone_log_type_e>(logType);
347 query_data.timestamp = static_cast<time_t>(time);
348 convertCallHistory(&query_data, callEntries);
351 ret = contacts_list_next(*recordList);
352 if (ret != CONTACTS_ERROR_NONE && ret != CONTACTS_ERROR_NO_DATA) {
353 LoggerD("callhistory parse error [" << ret << "]");
362 unsigned int CallHistory::convertAttrName(std::string &name)
364 std::string attrName("");
365 if (name.compare(STR_RP_REMOTEPARTY) == 0) {
366 return _contacts_phone_log.address;
367 } else if (name.compare(STR_START_TIME) == 0) {
368 return _contacts_phone_log.log_time;
369 } else if (name.compare(STR_DURATION) == 0) {
370 return _contacts_phone_log.extra_data1;
371 } else if (name.compare(STR_DIRECTION) == 0) {
372 return _contacts_phone_log.log_type;
373 } else if (name.compare(STR_ENTRY_ID) == 0) {
374 return _contacts_phone_log.id;
380 void CallHistory::OnRequestReceived(const EventCallHistoryPtr& event)
383 if (event->getCmdType() == EventCallHistory::CONNECT) {
384 if (contacts_connect2() == CONTACTS_ERROR_NONE) {
385 LoggerD("Successful to connect Call history DB by sub thread");
387 LoggerD("Failed to connect Call history DB by sub thread");
389 } else if (event->getCmdType() == EventCallHistory::DISCONNECT) {
390 if (contacts_disconnect2() == CONTACTS_ERROR_NONE) {
391 LoggerD("Successful to disconnect Call history DB by sub thread");
393 LoggerD("Failed to disconnect Call history DB by sub thread");
396 } catch (const Commons::PlatformException& ex) {
397 LoggerE("Exception: " << ex.GetMessage());
398 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
402 void CallHistory::OnRequestReceived(const EventFindCallHistoryPtr& event)
406 CallHistoryEntryListPtr callHistoryListPtr(new CallHistoryEntryList());
407 int ret = CONTACTS_ERROR_NONE;
409 contacts_query_h query = NULL;
410 contacts_filter_h filter = NULL;
411 contacts_list_h recordList = NULL;
412 bool isAscending = false;
416 contacts_query_create(_contacts_phone_log._uri, &query);
417 contacts_filter_create(_contacts_phone_log._uri, &filter);
419 CallHistoryFilterPtr filtering(new CallHistoryFilter(filter));
420 IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<IFilterVisitor>(filtering);
422 if (event->getFilterIsSet()) {
423 FilterPtr filterPtr = event->getFilter();
424 filterPtr->travel(filterTraversal, 0);
426 contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
427 contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
429 contacts_filter_add_int(filter, _contacts_phone_log.log_type, CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
431 contacts_query_set_filter(query, filter);
433 if (event->getSortModesIsSet()) {
434 if (event->getSortMode()->getOrder() == DeviceAPI::Tizen::ASCENDING_SORT_ORDER) {
439 std::string attriName(event->getSortMode()->getAttributeName());
440 ret = contacts_query_set_sort(query, convertAttrName(attriName), isAscending);
443 ret = contacts_query_set_sort(query, _contacts_phone_log.id, isAscending);
446 if (ret != CONTACTS_ERROR_NONE) {
447 LoggerD("callhistory query error [" << ret << "]");
451 if (event->getLimitIsSet()) {
452 limit = static_cast<int>(event->getLimit());
455 if (event->getOffsetIsSet()) {
456 offset = static_cast<int>(event->getOffset());
459 ret = contacts_db_get_records_with_query(query, offset, limit, &recordList);
461 if (ret != CONTACTS_ERROR_NONE) {
462 LoggerD("callhistory query error [" << ret << "]");
465 if (parseRecord(&recordList, callHistoryListPtr)) {
466 event->setResult(callHistoryListPtr);
469 contacts_list_destroy(recordList, true);
470 contacts_query_destroy(query);
471 contacts_filter_destroy(filter);
472 } catch (const Commons::PlatformException& ex) {
473 LoggerE("Exception: " << ex.GetMessage());
474 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
478 void CallHistory::OnRequestReceived(const EventRemoveBatchPtr& event)
483 std::vector<unsigned long> entryIds = event->getEntryIds();
484 unsigned int cnt = 0;
485 int ret = CONTACTS_ERROR_NONE;
486 list = new int[entryIds.size()];
488 for (cnt = 0; cnt < entryIds.size(); cnt++) {
489 list[cnt] = static_cast<int>(entryIds[cnt]);
492 if (entryIds.size() > 0) {
493 EventRemoveBatchDataPtr eventData( new EventCallHistoryPtrs<EventRemoveBatch>(event, this));
495 JSCallbackManagerPtr data = DPL::DynamicPointerCast<JSCallbackManager>(event->getPrivateData());
497 if (data->getOnSuccess() != NULL) {
498 ret = contacts_db_delete_records_async(_contacts_phone_log._uri, list, entryIds.size(), removeBatchCB, eventData.Get());
499 if (ret == CONTACTS_ERROR_NONE) {
500 m_removeBatchEvent.push_back(eventData);
501 event->switchToManualAnswer();
503 LoggerD("callhistory remove Batch error [" << ret << "]");
504 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
507 ret = contacts_db_delete_records(_contacts_phone_log._uri, list, entryIds.size());
508 if (ret != CONTACTS_ERROR_NONE) {
509 LoggerD("callhistory remove Batch error [" << ret << "]");
510 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
514 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
518 } catch (const Commons::PlatformException& ex) {
519 LoggerE("Exception: " << ex.GetMessage());
520 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
529 void CallHistory::OnRequestReceived(const EventRemoveAllPtr& event)
534 int ret = CONTACTS_ERROR_NONE;
535 contacts_list_h record_list = NULL;
536 contacts_record_h record = NULL;
537 unsigned int total = 0;
538 unsigned int cnt = 0;
541 ret = contacts_db_get_all_records(_contacts_phone_log._uri, 0, 0, &record_list);
543 if (record_list == NULL) {
544 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
548 contacts_list_get_count(record_list, &total);
550 list = new int[total];
551 LoggerD("total [" << total << "]");
552 for (unsigned int i = 0; i < total; i++) {
553 ret = contacts_list_get_current_record_p(record_list, &record);
555 if (record == NULL) {
556 ret = contacts_list_next(record_list);
557 if ( !(ret==CONTACTS_ERROR_NONE || ret==CONTACTS_ERROR_NO_DATA) ){
558 LoggerD("callhistory remove All error [" << ret << "]");
559 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
564 if (ret == CONTACTS_ERROR_NONE) {
565 ret = contacts_record_get_int(record, _contacts_phone_log.id , &value);
566 if (ret == CONTACTS_ERROR_NONE) {
572 ret = contacts_list_next(record_list);
573 if ( !(ret==CONTACTS_ERROR_NONE || ret==CONTACTS_ERROR_NO_DATA) ){
574 LoggerD("callhistory remove All error [" << ret << "]");
575 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
579 LoggerD("cnt [" << cnt << "]");
582 EventRemoveAllDataPtr eventData( new EventCallHistoryPtrs<EventRemoveAll>(event, this));
584 JSCallbackManagerPtr data = DPL::DynamicPointerCast<JSCallbackManager>(event->getPrivateData());
586 if (data->getOnSuccess() != NULL) {
587 ret = contacts_db_delete_records_async(_contacts_phone_log._uri, list, cnt, removeAllCB, eventData.Get());
588 if (ret == CONTACTS_ERROR_NONE) {
589 m_removeAllEvent.push_back(eventData);
590 event->switchToManualAnswer();
592 LoggerD("callhistory remove All error [" << ret << "]");
593 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
596 ret = contacts_db_delete_records(_contacts_phone_log._uri, list, cnt);
597 if (ret != CONTACTS_ERROR_NONE) {
598 LoggerD("callhistory remove All error [" << ret << "]");
599 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
605 contacts_list_destroy(record_list, true);
606 } catch (const Commons::PlatformException& ex) {
607 LoggerE("Exception: " << ex.GetMessage());
608 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
617 void CallHistory::callRemoveBatchEvent(int error, const EventRemoveBatchPtr &event)
619 if (error != CONTACTS_ERROR_NONE) {
620 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
623 EventRequestReceiver<EventRemoveBatch>::ManualAnswer(event);
625 std::vector<EventRemoveBatchDataPtr>::iterator it;
626 for (it = m_removeBatchEvent.begin(); it != m_removeBatchEvent.end(); ++it) {
627 if ((*it)->getEventPtrs() == event) {
628 m_removeBatchEvent.erase(it);
629 LoggerD("event is removed. (" << m_removeBatchEvent.size() << ")");
635 void CallHistory::callRemoveAllEvent(int error, const EventRemoveAllPtr &event)
637 if (error != CONTACTS_ERROR_NONE) {
638 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
641 EventRequestReceiver<EventRemoveAll>::ManualAnswer(event);
643 std::vector<EventRemoveAllDataPtr>::iterator it;
644 for (it = m_removeAllEvent.begin(); it != m_removeAllEvent.end(); ++it) {
645 if ((*it)->getEventPtrs() == event) {
646 m_removeAllEvent.erase(it);
647 LoggerD("event is removed. (" << m_removeAllEvent.size() << ")");
653 CallHistory::Watcher::Watcher(long handle, const EventCallHistoryListenerEmitterPtr& emitter) :
658 m_missedCallList = MissedCallListPtr(new MissedCallList());
659 if (contacts_connect2() == CONTACTS_ERROR_NONE) {
660 LoggerD("Successful to connect Call history DB ");
662 LoggerD("Failed to connect Call history DB ");
666 CallHistory::Watcher::~Watcher()
668 if (contacts_disconnect2() == CONTACTS_ERROR_NONE) {
669 LoggerD("Successful to disconnect Call history DB ");
671 LoggerD("Failed to disconnect Call history DB ");
675 void CallHistory::Watcher::stateHasChanged(CallHistoryEntryListPtr &entryList, EventCallHistoryListener::ResultStates state)
677 if (entryList == NULL)
682 EventCallHistoryListenerPtr event(new EventCallHistoryListener());
683 event->setResultState(state);
684 event->setResult(entryList);
685 m_emitter->emit(event);
688 void CallHistory::Watcher::stateHasRemoved(StringArrayPtr &entryList, EventCallHistoryListener::ResultStates state)
690 if (entryList == NULL)
695 EventCallHistoryListenerPtr event(new EventCallHistoryListener());
696 event->setResultState(state);
697 event->setRemoveResult(entryList);
698 m_emitter->emit(event);
702 bool CallHistory::Watcher::parseRecord(contacts_list_h *recordList, CallHistoryEntryListPtr &entryList)
704 CallHistory* callHistory = (CallHistory *) this;
705 if (callHistory != NULL) {
706 return callHistory->parseRecord(recordList, entryList);
711 bool CallHistory::Watcher::parseRemoveRecord(char* record, StringArrayPtr &removeRecords)
713 std::string recordStr(record);
714 removeRecords->push_back(recordStr);
719 void CallHistory::Watcher::ListenerCB(char* changes)
724 char* tokenType = NULL;
725 char* tokenId = NULL;
729 CallHistoryEntryListPtr callHistoryListPtr(new CallHistoryEntryList());
730 StringArrayPtr RemoveListPtr(new StringArray());
732 tokenType = strtok( changes, seps );
733 while( tokenType != NULL )
735 tokenId = strtok( NULL, seps );
736 LoggerD("[ %s / %s ]", tokenType , tokenId );
737 changeType = atoi((const char*)tokenType);
738 changeId = atoi((const char*)tokenId);
741 contacts_query_h query = NULL;
742 contacts_filter_h filter = NULL;
743 contacts_list_h recordList = NULL;
744 int ret = CONTACTS_ERROR_NONE;
746 contacts_query_create(_contacts_phone_log._uri, &query);
747 contacts_filter_create(_contacts_phone_log._uri, &filter);
748 contacts_filter_add_int(filter, _contacts_phone_log.id, CONTACTS_MATCH_EQUAL, changeId );
750 contacts_query_set_filter(query, filter);
752 ret = contacts_query_set_sort(query, _contacts_phone_log.id, false);
753 if (ret != CONTACTS_ERROR_NONE) {
754 LoggerD("callhistory query error [" << ret << "]");
757 ret = contacts_db_get_records_with_query(query, 0, 1, &recordList);
758 if (ret != CONTACTS_ERROR_NONE) {
759 contacts_list_destroy(recordList, true);
760 contacts_query_destroy(query);
761 contacts_filter_destroy(filter);
762 LoggerD("callhistory query error [" << ret << "]");
766 if((changeType == CONTACTS_CHANGE_INSERTED)||(changeType == CONTACTS_CHANGE_UPDATED)){
767 if (parseRecord(&recordList, callHistoryListPtr)) {
768 if (callHistoryListPtr->size() > 0) {
769 setCurrentLogId((*callHistoryListPtr)[0]->getEntryId());
772 }else if(changeType == CONTACTS_CHANGE_DELETED){
773 parseRemoveRecord(tokenId, RemoveListPtr);
776 contacts_list_destroy(recordList, true);
777 contacts_query_destroy(query);
778 contacts_filter_destroy(filter);
780 tokenType = strtok( NULL, seps );
784 if((changeType == CONTACTS_CHANGE_INSERTED)||(changeType == CONTACTS_CHANGE_UPDATED)){
785 if (callHistoryListPtr->size() > 0) {
786 setCurrentLogId((*callHistoryListPtr)[0]->getEntryId());
788 if(changeType == CONTACTS_CHANGE_INSERTED){
789 stateHasChanged(callHistoryListPtr, EventCallHistoryListener::ADDED);
790 }else if(changeType == CONTACTS_CHANGE_UPDATED){
791 stateHasChanged(callHistoryListPtr, EventCallHistoryListener::CHANGED);
795 }else if(changeType == CONTACTS_CHANGE_DELETED){
796 stateHasRemoved(RemoveListPtr, EventCallHistoryListener::REMOVED);