[Verification] Code compiles without errors.
onadded, onchanged and onremoved are called.
Change-Id: I324600be3c6df5af8bbd0e3e2831208929cfdf39
Signed-off-by: Tomasz Marciniak <t.marciniak@samsung.com>
#include "callhistory.h"
+#include <tapi_common.h>
+#include <ITapiSim.h>
+
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "callhistory_instance.h"
+#include "callhistory_types.h"
+#include "callhistory_utils.h"
+
+using namespace common;
+
namespace extension {
namespace callhistory {
-CallHistory::CallHistory()
+namespace {
+static void get_sim_msisdn_cb(TapiHandle *handle, int result, void *data, void *user_data)
{
+ LoggerD("Entered");
+
+ TelSimMsisdnList_t *list;
+ std::promise<std::string> *prom = reinterpret_cast<std::promise<std::string> *>(user_data);
+ char *number = NULL;
+
+ if (TAPI_SIM_ACCESS_SUCCESS == result) {
+ list = static_cast<TelSimMsisdnList_t *>(data);
+ if (list->count) {
+ number = list->list[0].num;
+ }
+ LoggerD("Phone number: %s", number);
+ } else {
+ LoggerE("Failed to access sim: %d", result);
+ }
+
+ std::string n = number ? std::string(number) : "";
+ prom->set_value(n);
+}
+}
+
+CallHistory::CallHistory():
+ m_is_listener_set(false)
+{
+ LoggerD("Entered");
+ if (CONTACTS_ERROR_NONE == contacts_connect()) {
+ LoggerD("Successful to connect Call history DB");
+ } else {
+ LoggerD("Failed to connect Call history DB");
+ }
+
+ loadPhoneNumbers();
}
CallHistory::~CallHistory()
{
+ LoggerD("Entered");
+
+ if (m_is_listener_set) {
+ int ret = contacts_db_remove_changed_cb_with_info(_contacts_phone_log._uri,
+ changeListenerCB, NULL);
+
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerW("Failed to remove ChangeListener");
+ }
+ }
+
+ if (CONTACTS_ERROR_NONE == contacts_disconnect()) {
+ LoggerD("Successful to disconnect Call history DB");
+ } else {
+ LoggerD("Failed to disconnect Call history DB");
+ }
}
CallHistory* CallHistory::getInstance(){
}
-long CallHistory::addChangeListener()
+std::vector<std::string>& CallHistory::getPhoneNumbers()
+{
+ return m_phone_numbers;
+}
+
+void CallHistory::changeListenerCB(const char* view_uri, char *changes, void* user_data)
{
+ LoggerD("Entered");
+
+ if (NULL == changes) {
+ LoggerW("changes is NULL");
+ return;
+ }
+ if (0 == strlen(changes)) {
+ LoggerW("changes is empty");
+ return;
+ }
+
+ char seps[] = ",:";
+ char* token_type = NULL;
+ char* token_id = NULL;
+ int change_type = 0;
+ int change_id = 0;
+
+ picojson::value added = picojson::value(picojson::object());
+ picojson::object& added_obj = added.get<picojson::object>();
+ picojson::array& added_array = added_obj.insert(std::make_pair(STR_DATA, picojson::value(
+ picojson::array()))).first->second.get<picojson::array>();
+
+ picojson::value changed = picojson::value(picojson::object());
+ picojson::object& changed_obj = changed.get<picojson::object>();
+ picojson::array& changed_array = changed_obj.insert(std::make_pair(STR_DATA, picojson::value(
+ picojson::array()))).first->second.get<picojson::array>();
+
+ picojson::value removed = picojson::value(picojson::object());
+ picojson::object& removed_obj = removed.get<picojson::object>();
+ picojson::array& removed_array = removed_obj.insert(std::make_pair(STR_DATA, picojson::value(
+ picojson::array()))).first->second.get<picojson::array>();
+
+ token_type = strtok(changes, seps);
+ while (NULL != token_type) {
+ token_id = strtok(NULL, seps);
+ change_type = atoi((const char*)token_type);
+
+ if (NULL != token_id) {
+ change_id = atoi((const char*)token_id);
+ } else {
+ LoggerD("There is no (more) changed Item : %s", token_id);
+ break;
+ }
+
+ contacts_query_h query = NULL;
+ contacts_filter_h filter = NULL;
+ contacts_list_h record_list = NULL;
+ int ret = CONTACTS_ERROR_NONE;
+ contacts_query_create(_contacts_phone_log._uri, &query);
+ contacts_filter_create(_contacts_phone_log._uri, &filter);
+ contacts_filter_add_int(filter, _contacts_phone_log.id, CONTACTS_MATCH_EQUAL, change_id);
+
+ contacts_query_set_filter(query, filter);
+ ret = contacts_query_set_sort(query, _contacts_phone_log.id, false);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Callhistory query error: %d", ret);
+ }
+
+ ret = contacts_db_get_records_with_query(query, 0, 1, &record_list);
+ if (CONTACTS_ERROR_NONE != ret) {
+ contacts_list_destroy(record_list, true);
+ contacts_query_destroy(query);
+ contacts_filter_destroy(filter);
+ LoggerD("Callhistory query error: %d", ret);
+ return;
+ }
+
+ if (CONTACTS_CHANGE_INSERTED == change_type) {
+ CallHistoryUtils::parseRecordList(&record_list, added_array);
+ } else if (CONTACTS_CHANGE_UPDATED == change_type) {
+ CallHistoryUtils::parseRecordList(&record_list, changed_array);
+ } else if (CONTACTS_CHANGE_DELETED == change_type) {
+ removed_array.push_back(picojson::value(token_id));
+ }
+
+ contacts_list_destroy(record_list, true);
+ contacts_query_destroy(query);
+ contacts_filter_destroy(filter);
+
+ token_type = strtok( NULL, seps);
+ }
+
+ if (added_array.size() > 0) {
+ added_obj[STR_ACTION] = picojson::value("onadded");
+ CallHistoryInstance::getInstance().CallHistoryChange(added_obj);
+ }
+ if (changed_array.size() > 0) {
+ changed_obj[STR_ACTION] = picojson::value("onchanged");
+ CallHistoryInstance::getInstance().CallHistoryChange(changed_obj);
+ }
+ if (removed_array.size() > 0) {
+ removed_obj[STR_ACTION] = picojson::value("onremoved");
+ CallHistoryInstance::getInstance().CallHistoryChange(removed_obj);
+ }
+}
+
+void CallHistory::startCallHistoryChangeListener()
+{
+ LoggerD("Entered");
+
+ if (!m_is_listener_set) {
+ int ret = contacts_db_add_changed_cb_with_info(_contacts_phone_log._uri,
+ changeListenerCB, NULL);
+
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerE("Failed to add ChangeListener");
+ throw UnknownException("Failed to add ChangeListener");
+ }
+ }
+
+ m_is_listener_set = true;
}
-void CallHistory::removeChangeListener()
+void CallHistory::stopCallHistoryChangeListener()
{
+ LoggerD("Entered");
+ if (m_is_listener_set) {
+ int ret = contacts_db_remove_changed_cb_with_info(_contacts_phone_log._uri,
+ changeListenerCB, NULL);
+
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerE("Failed to remove ChangeListener");
+ throw UnknownException("Failed to remove ChangeListener");
+ }
+ }
+
+ m_is_listener_set = false;
+}
+
+void CallHistory::loadPhoneNumbers()
+{
+ LoggerD("Entered");
+
+ char **cp_list = NULL;
+ cp_list = tel_get_cp_name_list();
+
+ if (!cp_list) {
+ LoggerE("Failed to get cp name list.");
+ return;
+ }
+
+ unsigned int modem_num = 0;
+ while (cp_list[modem_num]) {
+ std::string n = "";
+ TapiHandle* handle;
+ do {
+ std::promise<std::string> prom;
+ handle = tel_init(cp_list[modem_num]);
+ if (!handle) {
+ LoggerE("Failed to init tapi handle.");
+ break;
+ }
+
+ int card_changed;
+ TelSimCardStatus_t card_status;
+ int ret = tel_get_sim_init_info(handle, &card_status, &card_changed);
+ if (TAPI_API_SUCCESS != ret) {
+ LoggerE("Failed to get sim init info: %d", ret);
+ break;
+ }
+ LoggerD("Card status: %d Card Changed: %d", card_status, card_changed);
+ if (TAPI_SIM_STATUS_SIM_INIT_COMPLETED != card_status) {
+ LoggerW("SIM is not ready, we can't get other properties");
+ break;
+ }
+
+ ret = tel_get_sim_msisdn(handle, get_sim_msisdn_cb, &prom);
+ if (TAPI_API_SUCCESS != ret) {
+ LoggerE("Failed to get msisdn : %d", ret);
+ break;
+ }
+
+ auto fut = prom.get_future();
+ LoggerD("wait...");
+ fut.wait();
+ n = fut.get();
+ LoggerD("Phone number [%d] : %s", modem_num, n.c_str());
+ } while(false);
+
+ m_phone_numbers.push_back(n);
+ tel_deinit(handle);
+ modem_num++;
+ }
+ g_strfreev(cp_list);
}
} // namespace callhistory
#ifndef CALLHISTORY_CALLHISTORY_H_
#define CALLHISTORY_CALLHISTORY_H_
+#include <string>
+#include <vector>
+#include <future>
+#include <contacts.h>
+#include <contacts_internal.h>
+
namespace extension {
namespace callhistory {
+class CallHistoryInstance;
+
class CallHistory
{
public:
static CallHistory* getInstance();
+ std::vector<std::string>& getPhoneNumbers();
void find();
void remove();
void removeBatch();
void removeAll();
- long addChangeListener();
- void removeChangeListener();
+ void startCallHistoryChangeListener();
+ void stopCallHistoryChangeListener();
private:
CallHistory();
virtual ~CallHistory();
+ static void changeListenerCB(const char* view_uri, char *changes, void* user_data);
+ void loadPhoneNumbers();
+
+ bool m_is_listener_set;
+ std::vector<std::string> m_phone_numbers;
};
} // namespace callhistory
var Common = function() {
function _getException(type, msg) {
- return new WebAPIException(type, msg || 'Unexpected exception');
+ return new tizen.WebAPIException(type, msg || 'Unexpected exception');
}
function _getTypeMismatch(msg) {
function Common() {}
-function _prepareRequest(module, method, args) {
+function _prepareRequest(cmd, args) {
var request = {
- module : module
- };
- request.data = {
- method : method,
- args : args
+ cmd : cmd,
+ args : args || {}
};
+
return request;
}
-Common.prototype.getCallSync = function (msg) {
- var ret = extension.internal.sendSyncMessage(JSON.stringify(msg));
+Common.prototype.callSync = function (cmd, args) {
+ var request = _prepareRequest(cmd, args);
+ var ret = extension.internal.sendSyncMessage(JSON.stringify(request));
var obj = JSON.parse(ret);
if (obj.error) {
- throwException_(obj.error);
+ throw new tizen.throwException(obj.error);
}
return obj.result;
};
Common.prototype.getErrorObject = function (result) {
- return new WebAPIException(result.error);
+ return new tizen.WebAPIException(0, result.error.message, result.error.name);
};
Common.prototype.getResultObject = function (result) {
var C = _common.Common;
var _listeners = {};
-var _nextId = 0;
+var _listenersId = 0;
+
+function _createCallHistoryEntries(e) {
+ var entries_array = [];
+ var entries = e.data;
+
+ entries.forEach(function (data) {
+ entries_array.push(new CallHistoryEntry(data));
+ });
+
+ return entries_array;
+};
extension.setMessageListener(function(msg) {
+ var m = JSON.parse(msg);
+ if (m.cmd == 'CallHistoryChangeCallback') {
+ var d = null;
+
+ switch (m.action) {
+ case 'onadded':
+ case 'onchanged':
+ d = _createCallHistoryEntries(m);
+ break;
+
+ case 'onremoved':
+ d = m.data;
+ break;
+
+ default:
+ console.log('Unknown mode: ' + m.action);
+ return;
+ }
+ for (var watchId in _listeners) {
+ if (_listeners.hasOwnProperty(watchId) && _listeners[watchId][m.action]) {
+ _listeners[watchId][m.action](d);
+ }
+ }
+ }
});
function CallHistory() {
-}
+};
CallHistory.prototype.find = function() {
-}
+};
CallHistory.prototype.remove = function() {
-}
+};
CallHistory.prototype.removeBatch = function() {
-}
+};
CallHistory.prototype.removeAll = function() {
-}
+};
+
+CallHistory.prototype.addChangeListener = function() {
+ var args = AV.validateArgs(arguments, [
+ {
+ name : 'eventCallback',
+ type : AV.Types.LISTENER,
+ values : ['onadded', 'onchanged', 'onremoved']
+ }
+ ]);
-CallHistory.prototype.addChangeListener = function() {
+ if (T.isEmptyObject(_listeners)) {
+ C.callSync('CallHistory_addChangeListener');
+ }
-}
+ var watchId = ++_listenersId;
+ _listeners[watchId] = args.eventCallback;
+
+ return watchId;
+};
CallHistory.prototype.removeChangeListener = function() {
+ var args = AV.validateArgs(arguments, [
+ {
+ name : 'watchId',
+ type : AV.Types.LONG
+ }
+ ]);
-}
+ var id = args.watchId;
-function RemoteParty(data) {
+ if (T.isNullOrUndefined(_listeners[id])) {
+ throw new tizen.WebAPIException(0, 'NotFoundError', 'Watch id not found.');
+ }
-}
+ delete _listeners[id];
+
+ if (T.isEmptyObject(_listeners)) {
+ C.callSync('CallHistory_removeChangeListener');
+ }
+};
+
+function RemoteParty(data) {
+ Object.defineProperties(this, {
+ remoteParty: {
+ value: data.remoteParty ? data.remoteParty : null,
+ writable: false,
+ enumerable: true
+ },
+ personId: {
+ value: data.personId ? Converter.toString(data.personId) : null,
+ writable: false,
+ enumerable: true
+ }
+ });
+};
function CallHistoryEntry(data) {
-}
+ function directionSetter(val) {
+ direction = Converter.toString(val, false);
+ }
+
+ function createRemoteParties(parties) {
+ var parties_array = [];
+ parties.forEach(function (data) {
+ parties_array.push(new RemoteParty(data));
+ });
+ return parties_array;
+ }
+
+ var direction;
+ if (data) {
+ directionSetter(data.direction);
+ }
+
+ Object.defineProperties(this, {
+ uid: {value: Converter.toString(data.uid), writable: false, enumerable: true},
+ type: {value: data.type, writable: false, enumerable: true},
+ features : {
+ value: data.features ? data.features : null,
+ writable: false,
+ enumerable: true
+ },
+ remoteParties : {
+ value : createRemoteParties(data.remoteParties),
+ writable: false,
+ enumerable: true
+ },
+ startTime: {value: new Date(Number(data.startTime) * 1000),
+ writable: false,
+ enumerable: true
+ },
+ duration: {value: data.duration, writable: false, enumerable: true},
+ direction: {
+ enumerable: true,
+ set : directionSetter,
+ get : function() { return direction; }
+ },
+ callingParty: {
+ value: data.callingParty ? data.callingParty : null,
+ writable: false,
+ enumerable: true
+ },
+ });
+};
// Exports
-var CallHistoryObject = new CallHistory();
-
-exports.find = CallHistoryObject.find;
-exports.remove = CallHistoryObject.remove;
-exports.removeBatch = CallHistoryObject.removeBatch;
-exports.removeAll = CallHistoryObject.removeAll;
-exports.addChangeListener = CallHistoryObject.addChangeListener;
-exports.removeChangeListener = CallHistoryObject.removeChangeListener;
+exports = new CallHistory();
CallHistoryExtension::~CallHistoryExtension() {}
common::Instance* CallHistoryExtension::CreateInstance() {
- return new extension::callhistory::CallHistoryInstance;
+ return &extension::callhistory::CallHistoryInstance::getInstance();
}
using namespace common;
+CallHistoryInstance& CallHistoryInstance::getInstance() {
+ static CallHistoryInstance instance;
+ return instance;
+}
+
CallHistoryInstance::CallHistoryInstance() {
using namespace std::placeholders;
#define REGISTER_SYNC(c,x) \
RegisterSyncHandler(c, std::bind(&CallHistoryInstance::x, this, _1, _2));
- REGISTER_SYNC("remove", Remove);
- REGISTER_SYNC("addChangeListener", AddChangeListener);
- REGISTER_SYNC("removeChangeListener", RemoveChangeListener);
+ REGISTER_SYNC("CallHistory_remove", Remove);
+ REGISTER_SYNC("CallHistory_addChangeListener", AddChangeListener);
+ REGISTER_SYNC("CallHistory_removeChangeListener", RemoveChangeListener);
#undef REGISTER_SYNC
#define REGISTER_ASYNC(c,x) \
RegisterHandler(c, std::bind(&CallHistoryInstance::x, this, _1, _2));
- REGISTER_ASYNC("find", Find);
- REGISTER_ASYNC("removeBatch", RemoveBatch);
- REGISTER_ASYNC("removeAll", RemoveAll);
+ REGISTER_ASYNC("CallHistory_find", Find);
+ REGISTER_ASYNC("CallHistory_removeBatch", RemoveBatch);
+ REGISTER_ASYNC("CallHistory_removeAll", RemoveAll);
#undef REGISTER_ASYNC
}
}
void CallHistoryInstance::AddChangeListener(const picojson::value& args, picojson::object& out) {
-
+ LoggerD("Entered");
+ CallHistory::getInstance()->startCallHistoryChangeListener();
+ ReportSuccess(out);
}
void CallHistoryInstance::RemoveChangeListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+ CallHistory::getInstance()->stopCallHistoryChangeListener();
+ ReportSuccess(out);
+}
+
+void CallHistoryInstance::CallHistoryChange(picojson::object& data) {
+ LoggerD("Entered");
+ picojson::value event = picojson::value(data);
+ picojson::object& obj = event.get<picojson::object>();
+ obj["cmd"] = picojson::value("CallHistoryChangeCallback");
+ PostMessage(event.serialize().c_str());
}
} // namespace callhistory
class CallHistoryInstance : public common::ParsedInstance {
public:
+ static CallHistoryInstance& getInstance();
+
+ void CallHistoryChange(picojson::object& data);
+private:
CallHistoryInstance();
virtual ~CallHistoryInstance();
-private:
void Find(const picojson::value& args, picojson::object& out);
void Remove(const picojson::value& args, picojson::object& out);
void RemoveBatch(const picojson::value& args, picojson::object& out);
--- /dev/null
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CALLHISTORY_CALLHISTORY_TYPES_H_
+#define CALLHISTORY_CALLHISTORY_TYPES_H_
+
+namespace extension {
+namespace callhistory {
+
+#define STR_CALLTYPE_TEL "TEL"
+#define STR_CALLTYPE_XMPP "XMPP"
+#define STR_CALLTYPE_SIP "SIP"
+
+#define STR_CALL "CALL"
+#define STR_CALL_VOICE "VOICECALL"
+#define STR_CALL_VIDEO "VIDEOCALL"
+#define STR_CALL_EMERGENCY "EMERGENCYCALL"
+
+#define STR_DIALED "DIALED"
+#define STR_RECEIVED "RECEIVED"
+#define STR_MISSED_NEW "MISSEDNEW"
+#define STR_MISSED "MISSED"
+#define STR_REJECTED "REJECTED"
+#define STR_BLOCKED "BLOCKED"
+
+#define STR_DATA "data"
+#define STR_ACTION "action"
+#define STR_ENTRY_ID "uid"
+#define STR_CALL_TYPE "type"
+#define STR_TAGS "features"
+#define STR_REMOTE_PARTIES "remoteParties"
+#define STR_START_TIME "startTime"
+#define STR_DURATION "duration"
+#define STR_DIRECTION "direction"
+#define STR_CALLING_PARTY "callingParty"
+
+#define STR_REMOTE_PARTY "remoteParty"
+#define STR_PERSON_ID "personId"
+
+} // namespace callhistory
+} // namespace extension
+
+#endif // CALLHISTORY_CALLHISTORY_TYPES_H_
// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
+#include "callhistory_utils.h"
+#include "callhistory_types.h"
+#include "callhistory.h"
+#include "common/logger.h"
+
+namespace extension {
+namespace callhistory {
+
+void CallHistoryUtils::parseRecordList(contacts_list_h *record_list, picojson::array& array)
+{
+ LoggerD("Entered");
+
+ int ret = CONTACTS_ERROR_NONE;
+ contacts_record_h record = NULL;
+ int total = 0;
+
+ ret = contacts_list_get_count(*record_list, &total);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerW("Failed to get contacts list: %d", ret);
+ return;
+ }
+
+ for (int i = 0; i < total; i++) {
+ ret = contacts_list_get_current_record_p(*record_list, &record);
+ if (NULL != record) {
+ array.push_back(picojson::value(picojson::object()));
+ picojson::object& obj = array.back().get<picojson::object>();
+ parseRecord(&record, obj);
+ } else {
+ ret = contacts_list_next(*record_list);
+ if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
+ LoggerW("Callhistory list parse error: %d", ret);
+ return;
+ }
+ }
+ }
+}
+
+void CallHistoryUtils::parseRecord(contacts_record_h *record, picojson::object& obj)
+{
+ LoggerD("Entered");
+
+ int ret = CONTACTS_ERROR_NONE;
+ int int_data;
+
+ ret = contacts_record_get_int(*record, _contacts_phone_log.id, &int_data);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Failed to get contacts phone log id: %d", ret);
+ } else {
+ obj[STR_ENTRY_ID] = picojson::value(static_cast<double>(int_data));
+ }
+
+ ret = contacts_record_get_int(*record, _contacts_phone_log.log_type, &int_data);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Failed to get contacts phone log type: %d", ret);
+ } else {
+ parseLogType(static_cast<contacts_phone_log_type_e>(int_data), obj);
+ }
+
+ ret = contacts_record_get_int(*record, _contacts_phone_log.log_time, &int_data);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Failed to get contacts phone log time: %d", ret);
+ } else {
+ obj[STR_START_TIME] = picojson::value(static_cast<double>(int_data));
+ }
+
+ ret = contacts_record_get_int(*record, _contacts_phone_log.extra_data1, &int_data);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Failed to get contacts phone log extra data: %d", ret);
+ } else {
+ obj[STR_DURATION] = picojson::value(static_cast<double>(int_data));
+ }
+
+ parseRemoteParties(record, obj);
+ parseCallingParty(record, obj);
+}
+
+void CallHistoryUtils::parseLogType(contacts_phone_log_type_e log_type, picojson::object& obj)
+{
+ LoggerD("Entered");
+
+ picojson::value val = picojson::value(picojson::array());
+ picojson::array& features = val.get<picojson::array>();
+
+ switch(log_type) {
+ case CONTACTS_PLOG_TYPE_VOICE_INCOMMING:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_RECEIVED);
+ features.push_back(picojson::value(STR_CALL_VOICE));
+ break;
+ case CONTACTS_PLOG_TYPE_VOICE_OUTGOING:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_DIALED);
+ features.push_back(picojson::value(STR_CALL_VOICE));
+ break;
+ case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_MISSED);
+ features.push_back(picojson::value(STR_CALL_VOICE));
+ break;
+ case CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_MISSED_NEW);
+ features.push_back(picojson::value(STR_CALL_VOICE));
+ break;
+ case CONTACTS_PLOG_TYPE_VOICE_REJECT:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_REJECTED);
+ features.push_back(picojson::value(STR_CALL_VOICE));
+ break;
+ case CONTACTS_PLOG_TYPE_VOICE_BLOCKED:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_BLOCKED);
+ features.push_back(picojson::value(STR_CALL_VOICE));
+ break;
+ case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_RECEIVED);
+ features.push_back(picojson::value(STR_CALL_VIDEO));
+ break;
+ case CONTACTS_PLOG_TYPE_VIDEO_OUTGOING:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_DIALED);
+ features.push_back(picojson::value(STR_CALL_VIDEO));
+ break;
+ case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_MISSED);
+ features.push_back(picojson::value(STR_CALL_VIDEO));
+ break;
+ case CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_MISSED_NEW);
+ features.push_back(picojson::value(STR_CALL_VIDEO));
+ break;
+ case CONTACTS_PLOG_TYPE_VIDEO_REJECT:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_REJECTED);
+ features.push_back(picojson::value(STR_CALL_VIDEO));
+ break;
+ case CONTACTS_PLOG_TYPE_VIDEO_BLOCKED:
+ obj[STR_CALL_TYPE] = picojson::value(STR_CALLTYPE_TEL);
+ obj[STR_DIRECTION] = picojson::value(STR_BLOCKED);
+ features.push_back(picojson::value(STR_CALL_VIDEO));
+ break;
+ default:
+ LoggerW("Wrong phone log type: %d", log_type);
+ return;
+ }
+
+ if (features.size() > 0) {
+ obj.insert(std::make_pair(STR_TAGS, features));
+ }
+}
+
+void CallHistoryUtils::parseRemoteParties(contacts_record_h *record, picojson::object& obj)
+{
+ LoggerD("Entered");
+
+ int ret = CONTACTS_ERROR_NONE;
+ char * char_data = NULL;
+ int int_data;
+
+ picojson::array& remote_parties = obj.insert(std::make_pair(STR_REMOTE_PARTIES, picojson::value(
+ picojson::array()))).first->second.get<picojson::array>();
+ remote_parties.push_back(picojson::value(picojson::object()));
+ picojson::object& parties_obj = remote_parties.back().get<picojson::object>();
+
+ ret = contacts_record_get_int(*record, _contacts_phone_log.person_id, &int_data);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Failed to get contacts phone log person id: %d", ret);
+ } else {
+ parties_obj[STR_PERSON_ID] = picojson::value(static_cast<double>(int_data));
+ }
+
+ ret = contacts_record_get_str_p(*record, _contacts_phone_log.address, &char_data);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerD("Failed to get contacts phone log address: %d", ret);
+ } else if (NULL != char_data) {
+ parties_obj[STR_REMOTE_PARTY] = picojson::value(char_data);
+ }
+}
+
+void CallHistoryUtils::parseCallingParty(contacts_record_h *record, picojson::object& obj)
+{
+ LoggerD("Entered");
+
+ int ret = CONTACTS_ERROR_NONE;
+ const std::vector<std::string>& phone_numbers = CallHistory::getInstance()->getPhoneNumbers();
+ int sim_count = phone_numbers.size();
+ int sim_index;
+
+ ret = contacts_record_get_int(*record, _contacts_phone_log.sim_slot_no, &sim_index);
+ if (CONTACTS_ERROR_NONE != ret) {
+ LoggerW("Failed to get sim slot no. %d", ret);
+ }
+
+ if (sim_index >= sim_count) {
+ LoggerE("sim slot no. [%d] is out of count %d", sim_index, sim_count);
+ } else if (sim_index > 0) {
+ obj[STR_CALLING_PARTY] = picojson::value(phone_numbers.at(sim_index));
+ }
+}
+
+} // namespace callhistory
+} // namespace extension
// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
+#ifndef CALLHISTORY_CALLHISTORY_UTILS_H_
+#define CALLHISTORY_CALLHISTORY_UTILS_H_
+
+#include <contacts.h>
+#include <contacts_internal.h>
+
+#include "common/picojson.h"
+
+namespace extension {
+namespace callhistory {
+
+class CallHistoryUtils {
+public:
+ static void parseRecordList(contacts_list_h *record_list, picojson::array& array);
+ static void parseRecord(contacts_record_h *record, picojson::object& obj);
+ static void parseLogType(contacts_phone_log_type_e log_type, picojson::object& obj);
+ static void parseRemoteParties(contacts_record_h *record, picojson::object& obj);
+ static void parseCallingParty(contacts_record_h *record, picojson::object& obj);
+};
+
+} // namespace callhistory
+} // namespace extension
+
+#endif // CALLHISTORY_CALLHISTORY_UTILS_H_