b7065c79d22eba7ccc945f716f314ba4d4cfad5e
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Call / CallHistory.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. 
15  */
16
17
18 #include "CallHistory.h"
19
20 #include <vector>
21 #include <string>
22 #include <sstream>
23 #include <cassert>
24 #include <Commons/Exception.h>
25 #include <dpl/shared_ptr.h>
26 #include <dpl/log/log.h>
27 #include <API/Filter/IFilter.h>
28 #include <API/Filter/IFilterVisitor.h>
29 #include <calllog.h>
30
31 #include "CallHistoryFilter.h"
32
33 using namespace TizenApis::Api::Tizen;
34 using namespace TizenApis::Api::Call;
35 using namespace WrtDeviceApis;
36 using namespace WrtDeviceApis::Commons;
37 using namespace DPL;
38
39 namespace TizenApis {
40 namespace Platform {
41 namespace Call {
42
43 CallHistory::CallHistory()
44 {
45         _db_init();
46
47         if (calllog_connect() == CALLLOG_ERROR_NONE) {
48                 LogDebug("Successful to connect Call history DB ");
49         } else {
50                 LogDebug("Failed to connect Call history DB ");
51         }
52 }
53
54 CallHistory::~CallHistory()
55 {
56         _db_finish();
57         
58         if (calllog_disconnect() == CALLLOG_ERROR_NONE) {
59                 LogDebug("Successful to disconnect Call history DB ");
60         } else {
61                 LogDebug("Failed to disconnect Call history DB ");
62         }
63 }
64
65 bool CallHistory::convertCallHistory(callhistory_query_s *query_log, CallHistoryEntryListPtr &callEntries)
66 {
67         if (query_log == NULL || callEntries == NULL)
68                 return false;
69
70         CallHistoryEntryPropertiesPtr callHistoryItem(new CallHistoryEntryProperties());
71
72         std::string callType("");
73         std::string direction("");
74         std::string number("");
75         
76         if (query_log->phone_number != NULL) {
77                 number.append(query_log->phone_number);
78         }
79
80         switch(query_log->calllog_type) {
81         case CALLLOG_TYPE_VOICE_ANSWERED:
82                 callType.append("tel");
83                 direction.append("received");
84                 break;
85         case CALLLOG_TYPE_VOICE_OUTGOING:
86                 callType.append("tel");
87                 direction.append("dialed");
88                 break;
89         case CALLLOG_TYPE_VOICE_MISSED_CHECKED:
90                 callType.append("tel");
91                 direction.append("missed");
92                 break;
93         case CALLLOG_TYPE_VOICE_MISSED_UNCHECKED:
94                 callType.append("tel");
95                 direction.append("missed-new");
96                 break;
97         case CALLLOG_TYPE_VOICE_REJECTED:
98                 callType.append("tel");
99                 direction.append("rejected");
100                 break;
101         case CALLLOG_TYPE_VOICE_BLOCKED:
102                 callType.append("tel");
103                 direction.append("blocked");
104                 break;
105         case CALLLOG_TYPE_VIDEO_ANSWERED:
106                 callType.append("vt");
107                 direction.append("received");
108                 break;
109         case CALLLOG_TYPE_VIDEO_OUTGOING:
110                 callType.append("vt");
111                 direction.append("dialed");
112                 break;
113         case CALLLOG_TYPE_VIDEO_MISSED_CHECKED:
114                 callType.append("vt");
115                 direction.append("missed");
116                 break;
117         case CALLLOG_TYPE_VIDEO_MISSED_UNCHECKED:
118                 callType.append("vt");
119                 direction.append("missed-new");
120                 break;
121         case CALLLOG_TYPE_VIDEO_REJECTED:
122                 callType.append("vt");
123                 direction.append("rejected");
124                 break;
125         case CALLLOG_TYPE_VIDEO_BLOCKED:
126                 callType.append("vt");
127                 direction.append("blocked");
128                 break;
129         default:
130                 return false;
131         }
132
133         std::stringstream contactId;
134         contactId << query_log->contact_db_id;
135
136         callHistoryItem->setEntryId(query_log->calllog_db_id);
137         callHistoryItem->setCallType(callType);
138         callHistoryItem->setRemoteParty(number);
139         callHistoryItem->setContactId(contactId.str());
140         callHistoryItem->setStartTime(query_log->timestamp);
141         callHistoryItem->setDuration((unsigned long)(query_log->duration_sec));
142         callHistoryItem->setDirection(direction);
143
144         callEntries->insert(callEntries->end(), callHistoryItem);
145
146         return true;
147 }
148
149 void CallHistory::find(const EventFindCallHistoryPtr& event)
150 {
151         EventRequestReceiver<EventFindCallHistory>::PostRequest(event);
152 }
153
154 bool CallHistory::remove(const unsigned long entryId)
155 {
156         try {
157                 int ret = calllog_delete_from_db(entryId);
158
159                 if (ret == CALLLOG_ERROR_NONE) {
160                         return true;
161                 } else {
162                         return false;
163                 }
164         } catch (const Commons::PlatformException& ex) {
165                 ThrowMsg(Commons::PlatformException, ex.GetMessage());
166         }
167 }
168
169 void CallHistory::removeBatch(const EventRemoveBatchPtr& event)
170 {
171         EventRequestReceiver<EventRemoveBatch>::PostRequest(event);
172 }
173
174 bool CallHistory::executeQuery(std::string &query, CallHistoryEntryListPtr &callEntries)
175 {
176         callhistory_query_s query_data;
177
178         stmt hstmt = NULL;
179         int ret = 0;
180
181         hstmt = _query_prepare((char *)(query.c_str()));
182
183         do {
184                 ret = _query_step(hstmt);
185                 if (ret == SQLITE_ROW) {
186                         query_data.calllog_db_id = (unsigned long)_query_column_int64(hstmt, 0);
187                         query_data.calllog_type = (calllog_type_e)_query_column_int(hstmt, 1);
188                         query_data.contact_db_id = _query_column_int(hstmt, 2);
189                         query_data.phone_number = _query_column_text(hstmt, 3);
190                         query_data.timestamp = (time_t)_query_column_int(hstmt, 4);
191                         query_data.duration_sec = _query_column_int(hstmt, 5);
192                         
193                         convertCallHistory(&query_data, callEntries);
194                 } else if (ret == SQLITE_DONE) {
195                         break;
196                 } else {
197                         break;
198                 }
199         } while (1);
200
201         _query_finalize(hstmt);
202         return true;
203 }
204
205 std::string CallHistory::convertAttrName(std::string &name)
206 {
207         std::string attrName("");
208         if (name.compare("remoteParty") == 0) {
209                 return attrName.append("number");
210         } else if (name.compare("startTime") == 0) {
211                 return attrName.append("log_time");
212         } else if (name.compare("duration") == 0) {
213                 return attrName.append("data1");
214         } else if (name.compare("direction") == 0) {
215                 return attrName.append("log_type");
216         } else {
217                 return attrName;
218         }
219 }
220
221 std::string CallHistory::makeQuerySortMode(SortModeArrayPtr attr)
222 {
223         std::string query("");
224         std::string attriName;
225         int cnt = 0;
226         SortModeArray::iterator it = attr->begin();
227         
228
229         for (;it!=attr->end(); ++it) {
230                 attriName = (*it)->getAttributeName();
231                 attriName = convertAttrName(attriName);
232                 if (attriName.compare("") != 0) { 
233                         if (cnt == 0) {
234                                 query.append(" ORDER BY ");
235                         } else {
236                                 query.append(", ");
237                         }
238                         query.append(attriName);
239
240                         if ((*it)->getOrder() == Api::Tizen::ASCENDING_SORT_ORDER) {
241                                 query.append(" ASC");
242                         } else {
243                                 query.append(" DESC");
244                         }
245                         cnt++;
246                 }
247         }
248
249         return query;
250 }
251
252 void CallHistory::OnRequestReceived(const EventFindCallHistoryPtr& event)
253 {
254         try {
255                 CallHistoryEntryListPtr callHistoryListPtr(new CallHistoryEntryList());
256
257                 std::string query ("SELECT id, log_type, contact_id, number, log_time, data1 FROM phonelogs");
258
259                 CallHistoryFilterPtr filtering(new CallHistoryFilter());
260                 IFilterVisitorPtr filterTraversal = DPL::StaticPointerCast<IFilterVisitor>(filtering);
261
262                 if (event->getFilterIsSet()) {
263                         FilterPtr filter = event->getFilter();
264                         filter->travel(filterTraversal, 0);
265                         query.append(filtering->getResult());
266                         query.append(" AND log_type <= 12");
267                 } else {
268                         query.append(" WHERE log_type <= 12");
269                 }
270
271                 if (event->getSortModesIsSet()) {
272                         query.append(makeQuerySortMode(event->getSortMode()));
273                 } else {
274                         query.append(" ORDER BY log_time DESC");
275                 }
276
277                 if (event->getLimitIsSet()) {
278                         query.append(" LIMIT ");
279                         std::stringstream limitStream;
280                         limitStream << event->getLimit();
281                         query.append(limitStream.str());
282                         if (event->getOffsetIsSet()) {
283                                 query.append(" OFFSET ");
284                                 std::stringstream offsetStream;
285                                 offsetStream << event->getOffset();
286                                 query.append(offsetStream.str());
287                         }
288                 }
289
290                 LogDebug("execute query [" << query << "]");
291
292                 executeQuery(query, callHistoryListPtr);
293                 event->setResult(callHistoryListPtr);
294
295         } catch (const Commons::PlatformException& ex) {
296                 LogError("Exception: " << ex.GetMessage());
297                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
298         }
299 }
300
301 void CallHistory::OnRequestReceived(const EventRemoveBatchPtr& event)
302 {
303         try {
304                 std::vector<unsigned long> entryIds = event->getEntryIds();
305                 unsigned int cnt = 0;
306                 int ret = CALLLOG_ERROR_NONE;
307                 for (cnt = 0; cnt < entryIds.size(); cnt++) {
308                         ret = calllog_delete_from_db(static_cast<int>(entryIds[cnt]));
309                         if (ret != CALLLOG_ERROR_NONE) {
310                                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
311                         }
312                 }
313         } catch (const Commons::PlatformException& ex) {
314                 LogError("Exception: " << ex.GetMessage());
315                 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
316         }
317 }
318
319 }
320 }
321 }
322