[Callhistory] Added find method implementation.
authorTomasz Marciniak <t.marciniak@samsung.com>
Tue, 16 Dec 2014 10:42:32 +0000 (11:42 +0100)
committerTomasz Marciniak <t.marciniak@samsung.com>
Sun, 21 Dec 2014 07:01:36 +0000 (08:01 +0100)
[Verification] Code compiles without errors.
find() returns CallHistoryEntry array.
TCT passrate 100%

Change-Id: Ia04876dd7c74cc25e3a884904953ce1df1840e65
Signed-off-by: Tomasz Marciniak <t.marciniak@samsung.com>
src/callhistory/callhistory.cc
src/callhistory/callhistory.h
src/callhistory/callhistory_api.js
src/callhistory/callhistory_instance.cc
src/callhistory/callhistory_types.h
src/callhistory/callhistory_utils.cc
src/callhistory/callhistory_utils.h

index 0c20ecdd82ee8b769f173585b06a760d7e804424..58ebd5b6d675925606fd07203e2d76c0e973e9c0 100644 (file)
@@ -62,8 +62,8 @@ CallHistory::CallHistory():
     } else {
         LoggerD("Failed to connect Call history DB");
     }
-
-    loadPhoneNumbers();
+    //TODO Uncomment below line if getting sim info will be possible
+    //loadPhoneNumbers();
 }
 
 CallHistory::~CallHistory()
@@ -91,9 +91,166 @@ CallHistory* CallHistory::getInstance(){
     return &instance;
 }
 
-void CallHistory::find()
+void CallHistory::find(const picojson::object& args)
 {
+    LoggerD("Entered");
+
+    const auto it_args_end = args.end();
+    const auto it_filter = args.find("filter");
+    picojson::object filter_obj;
+    if (it_filter != it_args_end &&
+            it_filter->second.is<picojson::object>()) {
+        filter_obj = it_filter->second.get<picojson::object>();
+    }
+
+    const auto it_sort_mode = args.find("sortMode");
+    picojson::object sort_mode;
+    if (it_sort_mode != it_args_end &&
+            it_sort_mode->second.is<picojson::object>()) {
+        sort_mode = it_sort_mode->second.get<picojson::object>();
+    }
+
+    std::string sort_attr_name;
+    std::string sort_order;
+    if (!sort_mode.empty()) {
+        const auto it_sort_end = sort_mode.end();
+        const auto it_sort_attr_name = sort_mode.find("attributeName");
+        if (it_sort_attr_name != it_sort_end &&
+            it_sort_attr_name->second.is<std::string>()) {
+            sort_attr_name = it_sort_attr_name->second.get<std::string>();
+        }
+
+        const auto it_sort_order = sort_mode.find("order");
+        if (it_sort_order != it_sort_end &&
+            it_sort_order->second.is<std::string>()) {
+            sort_order = it_sort_order->second.get<std::string>();
+        }
+    }
+
+    const auto it_limit = args.find("limit");
+    int limit = 0;
+    if (it_limit != it_args_end &&
+        it_limit->second.is<double>()) {
+        limit = static_cast<int>(it_limit->second.get<double>());
+    }
+
+    const auto it_offset = args.find("offset");
+    int offset = 0;
+    if (it_offset != it_args_end &&
+        it_offset->second.is<double>()) {
+        offset = static_cast<int>(it_offset->second.get<double>());
+    }
+
+    const double callback_id = args.find("callbackId")->second.get<double>();
+    int phone_numbers = m_phone_numbers.size();
+
+    auto find = [filter_obj, sort_attr_name, sort_order, limit, offset, phone_numbers](
+            const std::shared_ptr<picojson::value>& response) -> void {
+        contacts_query_h query = NULL;
+        contacts_filter_h filter = NULL;
+        contacts_list_h record_list = NULL;
+
+        try {
+            if (phone_numbers == 0) {
+                LoggerE("Phone numbers list is empty.");
+                //Uncomment below line if gettin sim info will be possible (loadPhonesNumbers)
+                //throw UnknownException("Phone numbers list is empty.");
+            }
+
+            int ret = CONTACTS_ERROR_NONE;
+            ret = contacts_connect_on_thread();
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_connect_on_thread failed");
+            }
+
+            ret = contacts_query_create(_contacts_phone_log._uri, &query);
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_query_create failed");
+            }
+
+            ret = contacts_filter_create(_contacts_phone_log._uri, &filter);
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_filter_create failed");
+            }
+
+            //filter
+            if (!filter_obj.empty()) {
+                LoggerD("Filter is set");
+                CallHistoryUtils::createFilter(filter, filter_obj);
+                ret = contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_AND);
+                if (CONTACTS_ERROR_NONE != ret) {
+                    LoggerW("contacts_filter_add_operator failed");
+                }
+            }
+
+            ret = contacts_filter_add_int(filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_filter_add_int failed");
+            }
+
+            ret = contacts_query_set_filter(query, filter);
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_query_set_filter failed");
+            }
+
+            //sort mode
+            bool is_asc = false;
+            if (!sort_order.empty()) {
+                if (STR_ORDER_ASC == sort_order) {
+                    is_asc = true;
+                }
+                unsigned int attribute = CallHistoryUtils::convertAttributeName(sort_attr_name);
+                ret = contacts_query_set_sort(query, attribute, is_asc);
+            } else {
+                ret = contacts_query_set_sort(query, _contacts_phone_log.id, is_asc);
+            }
+
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_query_set_sort failed");
+            }
+
+            //get records with limit and offset
+            ret = contacts_db_get_records_with_query(query, offset, limit, &record_list);
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_db_get_records_with_query failed");
+            }
+
+            picojson::object& obj = response->get<picojson::object>();
+            picojson::array& array = obj.insert(std::make_pair(STR_DATA, picojson::value(
+                                     picojson::array()))).first->second.get<picojson::array>();
+            if (record_list) {
+                CallHistoryUtils::parseRecordList(&record_list, array);
+            }
+
+            contacts_list_destroy(record_list, true);
+            contacts_query_destroy(query);
+            contacts_filter_destroy(filter);
 
+            ret = contacts_disconnect_on_thread();
+            if (CONTACTS_ERROR_NONE != ret) {
+                LoggerW("contacts_disconnect_on_thread failed");
+            }
+
+            ReportSuccess(response->get<picojson::object>());
+        } catch (const PlatformException& err) {
+            contacts_list_destroy(record_list, true);
+            contacts_query_destroy(query);
+            contacts_filter_destroy(filter);
+            ReportError(err, response->get<picojson::object>());
+        }
+    };
+
+    auto find_response = [callback_id](const std::shared_ptr<picojson::value>& response) -> void {
+        picojson::object& obj = response->get<picojson::object>();
+        obj.insert(std::make_pair("callbackId", callback_id));
+        CallHistoryInstance::getInstance().PostMessage(response->serialize().c_str());
+    };
+
+    TaskQueue::GetInstance().Queue<picojson::value>(
+            find,
+            find_response,
+            std::shared_ptr<picojson::value>(new picojson::value(picojson::object())));
 }
 
 void CallHistory::remove(const picojson::object& args)
index 52a84335204318e6d372f1013ae878426feccbe9..71b58084d8fcc32499067871381040ea7315e62d 100644 (file)
@@ -23,7 +23,7 @@ public:
     static CallHistory* getInstance();
     std::vector<std::string>& getPhoneNumbers();
 
-    void find();
+    void find(const picojson::object& args);
     void remove(const picojson::object& args);
     void removeBatch(const picojson::object& args);
     void removeAll(const picojson::object& args);
index 4b818d5f893c5473743ae43eb6ac210493a26dea..bba067ad646cd75d14cdfd9893e09e15e41d57ab 100644 (file)
@@ -272,7 +272,67 @@ function CallHistory() {
 };
 
 CallHistory.prototype.find = function() {
+    var args = AV.validateArgs(arguments, [
+        {
+            name : 'successCallback',
+            type : AV.Types.FUNCTION,
+        },
+        {
+            name : 'errorCallback',
+            type : AV.Types.FUNCTION,
+            optional : true,
+            nullable : true
+        },
+        {
+            name : 'filter',
+            type : AV.Types.PLATFORM_OBJECT,
+            optional : true,
+            nullable : true,
+            values : [tizen.AttributeFilter,
+                      tizen.AttributeRangeFilter,
+                      tizen.CompositeFilter]
+        },
+        {
+            name : 'sortMode',
+            type : AV.Types.PLATFORM_OBJECT,
+            optional : true,
+            nullable : true,
+            values : tizen.SortMode
+        },
+        {
+            name : 'limit',
+            type : AV.Types.UNSIGNED_LONG,
+            optional : true,
+            nullable : true
+        },
+        {
+            name : 'offset',
+            type : AV.Types.UNSIGNED_LONG,
+            optional : true,
+            nullable : true
+        }
+    ]);
+
+    var callback = function(result) {
+        if (C.isFailure(result)) {
+            C.callIfPossible(args.errorCallback, C.getErrorObject(result));
+        } else {
+            var entries = _createCallHistoryEntries(result);
+            C.callIfPossible(args.successCallback(entries));
+        }
+    };
+
+    var callbackId = ++_callbackId;
+    _callbacks[callbackId] = callback;
+
+    var callArgs = {};
+    callArgs.callbackId = callbackId;
+    callArgs.filter = args.filter;
+    callArgs.sortMode = args.sortMode;
+    callArgs.limit = args.limit;
+    callArgs.offset = args.offset;
 
+    C.call('CallHistory_find', callArgs, callback);
 };
 
 CallHistory.prototype.remove = function() {
@@ -395,7 +455,8 @@ CallHistory.prototype.removeChangeListener = function() {
     var id = args.watchId;
 
     if (T.isNullOrUndefined(_listeners[id])) {
-        throw new tizen.WebAPIException(0, 'NotFoundError', 'Watch id not found.');
+        throw new tizen.WebAPIException(
+                tizen.WebAPIException.INVALID_VALUES_ERR, 'Watch id not found.');
     }
 
     delete _listeners[id];
index d3eafe6c5668a698d7f6dbb95b9714bec6189b94..f14785e5c920ab043d2cd3d89a8ad7a16ca951fd 100644 (file)
@@ -44,7 +44,8 @@ CallHistoryInstance::~CallHistoryInstance() {
 }
 
 void CallHistoryInstance::Find(const picojson::value& args, picojson::object& out) {
-
+    LoggerD("Entered");
+    CallHistory::getInstance()->find(args.get<picojson::object>());
 }
 
 void CallHistoryInstance::Remove(const picojson::value& args, picojson::object& out) {
index 262bc217f50e8946f807806ec572f6c0f1031cf9..5a2ccf010c2db4c73ff01513e21c472959ec777f 100644 (file)
@@ -38,6 +38,18 @@ namespace callhistory {
 #define STR_REMOTE_PARTY "remoteParty"
 #define STR_PERSON_ID "personId"
 
+#define STR_RP_REMOTEPARTY "remoteParties.remoteParty"
+#define STR_RP_PERSONID "remoteParties.personId"
+
+#define STR_ORDER_ASC "ASC"
+
+#define STR_FILTER_EXACTLY "EXACTLY"
+#define STR_FILTER_FULLSTRING "FULLSTRING"
+#define STR_FILTER_CONTAINS "CONTAINS"
+#define STR_FILTER_STARTSWITH "STARTSWITH"
+#define STR_FILTER_ENDSWITH "ENDSWITH"
+#define STR_FILTER_EXISTS "EXISTS"
+
 } // namespace callhistory
 } // namespace extension
 
index 49ddb5f3645ced18730af24cd4592ccb37f11f10..f234b9d79d9f2404908448032081830eb9396540 100644 (file)
@@ -3,6 +3,10 @@
 // found in the LICENSE file.
 
 #include "callhistory_utils.h"
+
+#include <stack>
+#include <ctime>
+
 #include "callhistory_types.h"
 #include "callhistory.h"
 #include "common/logger.h"
 namespace extension {
 namespace callhistory {
 
+namespace {
+enum FilterTypeEnum {
+    FILTER_ATTRIBUTE = 0,
+    FILTER_ATTRIBUTE_RANGE = 1,
+    FILTER_COMPOSITE = 2,
+    FILTER_UNKNOWN = 3
+};
+
+enum CompositeTypeEnum {
+    UNION = 0,
+    INTERSECTION = 1,
+    NONE = 2
+};
+}
+
 void CallHistoryUtils::parseRecordList(contacts_list_h *record_list, picojson::array& array)
 {
     LoggerD("Entered");
@@ -37,6 +56,11 @@ void CallHistoryUtils::parseRecordList(contacts_list_h *record_list, picojson::a
                 return;
             }
         }
+        ret = contacts_list_next(*record_list);
+        if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
+            LoggerW("Callhistory list parse error: %d", ret);
+            return;
+        }
     }
 }
 
@@ -206,5 +230,423 @@ void CallHistoryUtils::parseCallingParty(contacts_record_h *record, picojson::ob
     }
 }
 
+unsigned int CallHistoryUtils::convertAttributeName(const std::string attribute_name)
+{
+    LoggerD("Entered");
+
+    if (STR_RP_REMOTEPARTY == attribute_name) {
+        return _contacts_phone_log.address;
+    } else if (STR_START_TIME == attribute_name) {
+        return _contacts_phone_log.log_time;
+    } else if (STR_DURATION == attribute_name) {
+        return _contacts_phone_log.extra_data1;
+    } else if (STR_DIRECTION == attribute_name) {
+        return _contacts_phone_log.log_type;
+    } else if (STR_ENTRY_ID == attribute_name) {
+        return _contacts_phone_log.id;
+    } else {
+        return 0;
+    }
+}
+
+static FilterTypeEnum getFilterType(const picojson::object &filter)
+{
+    const auto it_end = filter.end();
+
+    FilterTypeEnum type = FILTER_UNKNOWN;
+
+    const auto it_match_flag = filter.find("matchFlag");
+    if (it_match_flag != it_end) {
+        type = FILTER_ATTRIBUTE;
+    }
+
+    const auto it_initial_value = filter.find("initialValue");
+    const auto it_end_value = filter.find("endValue");
+    if (it_initial_value != it_end && it_end_value != it_end) {
+        type = FILTER_ATTRIBUTE_RANGE;
+    }
+
+    const auto it_type = filter.find("type");
+    if (it_type != it_end) {
+        type = FILTER_COMPOSITE;
+    }
+    return type;
+}
+
+static CompositeTypeEnum getCompositeType(const picojson::object &filter)
+{
+    CompositeTypeEnum type = NONE;
+    const std::string& str_type = filter.find("type")->second.get<std::string>();
+
+    if ("UNION" == str_type) {
+        type = UNION;
+    } else if ("INTERSECTION" == str_type) {
+        type = INTERSECTION;
+    }
+    return type;
+}
+
+static contacts_match_str_flag_e getMatchFlag(const std::string& match_flag)
+{
+    if (STR_FILTER_FULLSTRING == match_flag) {
+        return CONTACTS_MATCH_FULLSTRING;
+    } else if (STR_FILTER_CONTAINS == match_flag) {
+        return CONTACTS_MATCH_CONTAINS;
+    } else if (STR_FILTER_STARTSWITH == match_flag) {
+        return CONTACTS_MATCH_STARTSWITH;
+    } else if (STR_FILTER_ENDSWITH == match_flag) {
+        return CONTACTS_MATCH_ENDSWITH;
+    } else if (STR_FILTER_EXISTS == match_flag) {
+        return CONTACTS_MATCH_EXISTS;
+    } else {
+        return CONTACTS_MATCH_EXACTLY;
+    }
+}
+
+static std::time_t toTimeT(const std::string &value)
+{
+    struct tm date;
+    if (nullptr == strptime(value.c_str(), "%Y-%m-%dT%H:%M:%S", &date)) {
+        LOGW("Couldn't convert supplied date.");
+    }
+    return mktime(&date);
+}
+
+static void visitAttribute(std::stack<contacts_filter_h>& stack, const picojson::object filter)
+{
+    LoggerD("Entered");
+
+    contacts_filter_h filter_top = stack.top();
+    contacts_filter_h sub_filter = NULL;
+    contacts_filter_create(_contacts_phone_log._uri, &sub_filter);
+
+    const auto it_attr_name = filter.find("attributeName");
+    const std::string &attr_name = it_attr_name->second.get<std::string>();
+
+    const auto it_match_flag = filter.find("matchFlag");
+    const std::string &match_flag = it_match_flag->second.get<std::string>();
+    contacts_match_str_flag_e c_match_flag = getMatchFlag(match_flag);
+
+    const auto it_match_value = filter.find("matchValue");
+    std::string match_value_str;
+    if (!it_match_value->second.is<picojson::null>()) {
+        if (it_match_value->second.is<double>()) {
+            match_value_str = std::to_string(it_match_value->second.get<double>());
+        } else {
+            match_value_str = it_match_value->second.get<std::string>();
+        }
+    }
+
+    if (STR_DIRECTION == attr_name) {
+        if (STR_RECEIVED == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_INCOMMING);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_DIALED == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_OUTGOING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_OUTGOING);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_MISSED == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_MISSED_NEW == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_REJECTED == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_REJECT);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_REJECT);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_BLOCKED == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_BLOCKED);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else {
+            contacts_filter_add_int(filter_top, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_NONE);
+        }
+    }
+    else if (STR_TAGS == attr_name) {
+        if (STR_CALL == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_GREATER_THAN_OR_EQUAL,
+                    CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_CALL_VOICE == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_OUTGOING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_REJECT);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VOICE_BLOCKED);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_CALL_VIDEO == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_INCOMMING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_OUTGOING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_REJECT);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_OR);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else if (STR_CALL_EMERGENCY == match_value_str) {
+            contacts_filter_add_str(filter_top, _contacts_phone_log.extra_data2,
+                    CONTACTS_MATCH_EXACTLY, "001");
+        }
+        else {
+            contacts_filter_add_int(filter_top, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_NONE);
+        }
+    }
+    else if (STR_RP_REMOTEPARTY == attr_name) {
+        contacts_filter_add_str(filter_top, _contacts_phone_log.address, c_match_flag,
+                match_value_str.c_str());
+    }
+    else if (STR_RP_PERSONID == attr_name) {
+        contacts_filter_add_str(filter_top, _contacts_phone_log.person_id, c_match_flag,
+                match_value_str.c_str());
+    }
+    else if (STR_START_TIME == attr_name) {
+        LoggerD("DATE _____>>>>>>>>> %s", match_value_str.c_str());
+        contacts_filter_add_int(filter_top, _contacts_phone_log.log_time,
+                CONTACTS_MATCH_EQUAL, static_cast<int>(toTimeT(match_value_str)));
+    }
+    else if (STR_DURATION == attr_name) {
+        contacts_filter_add_str(filter_top, _contacts_phone_log.extra_data1, c_match_flag,
+                match_value_str.c_str());
+    }
+    else if (STR_CALL_TYPE == attr_name) {
+        if (STR_CALLTYPE_TEL == match_value_str) {
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_GREATER_THAN_OR_EQUAL,
+                    CONTACTS_PLOG_TYPE_VOICE_INCOMMING);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
+            contacts_filter_add_int(sub_filter, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_LESS_THAN_OR_EQUAL, CONTACTS_PLOG_TYPE_VIDEO_BLOCKED);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+        else {
+            contacts_filter_add_int(filter_top, _contacts_phone_log.log_type,
+                    CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_NONE);
+        }
+    }
+    else if (STR_ENTRY_ID == attr_name) {
+        contacts_filter_add_str(filter_top, _contacts_phone_log.id, c_match_flag,
+                match_value_str.c_str());
+    }
+    else {
+        contacts_filter_add_int(filter_top, _contacts_phone_log.log_type,
+                CONTACTS_MATCH_EQUAL, CONTACTS_PLOG_TYPE_NONE);
+    }
+
+    contacts_filter_destroy(sub_filter);
+}
+
+static void visitAttributeRange(std::stack<contacts_filter_h>& stack, const picojson::object filter)
+{
+    LoggerD("Entered");
+
+    unsigned int prop_id = 0;
+    const auto it_attr_name = filter.find("attributeName");
+    const std::string &attr_name = it_attr_name->second.get<std::string>();
+
+    if (STR_RP_REMOTEPARTY == attr_name) {
+        prop_id = _contacts_phone_log.address;
+    } else if (STR_RP_PERSONID == attr_name) {
+        prop_id = _contacts_phone_log.person_id;
+    } else if (STR_START_TIME == attr_name) {
+        prop_id = _contacts_phone_log.log_time;
+    } else if (STR_DURATION == attr_name) {
+        prop_id = _contacts_phone_log.extra_data1;
+    } else if (STR_ENTRY_ID == attr_name) {
+        prop_id = _contacts_phone_log.id;
+    } else {
+        LoggerW("attribute: %s is not supported", attr_name.c_str());
+        return;
+    }
+
+    std::string i_val;
+    std::string e_val;
+    contacts_filter_h filter_top = stack.top();
+    contacts_filter_h sub_filter = NULL;
+
+    const auto it_initial_value = filter.find("initialValue");
+    const auto it_end_value = filter.find("endValue");
+    bool is_i_val_null = it_initial_value->second.is<picojson::null>();
+    bool is_e_val_null = it_end_value->second.is<picojson::null>();
+
+    if (!is_i_val_null) {
+        if (it_initial_value->second.is<double>()) {
+            i_val = std::to_string(it_initial_value->second.is<double>());
+        } else {
+            i_val = it_initial_value->second.get<std::string>();
+        }
+    }
+
+    if (!is_e_val_null) {
+        if (it_end_value->second.is<double>()) {
+            e_val = std::to_string(it_end_value->second.is<double>());
+        } else {
+            e_val = it_end_value->second.get<std::string>();
+        }
+    }
+
+    contacts_filter_create(_contacts_phone_log._uri, &sub_filter);
+
+    if (_contacts_phone_log.address == prop_id) {
+        if (!is_i_val_null && is_e_val_null) {
+            contacts_filter_add_str(filter_top, prop_id, CONTACTS_MATCH_STARTSWITH,i_val.c_str());
+        }
+        else if (is_i_val_null && !is_e_val_null) {
+            contacts_filter_add_str(filter_top, prop_id, CONTACTS_MATCH_ENDSWITH, e_val.c_str());
+        }
+        else if (!is_i_val_null && !is_e_val_null) {
+            contacts_filter_add_str(sub_filter, prop_id, CONTACTS_MATCH_STARTSWITH, i_val.c_str());
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
+            contacts_filter_add_str(sub_filter, prop_id, CONTACTS_MATCH_ENDSWITH, e_val.c_str());
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+    }
+    else {
+        int i_val_int = atoi(i_val.c_str());
+        int e_val_int = atoi(e_val.c_str());
+
+        if (!is_i_val_null && is_e_val_null) {
+            contacts_filter_add_int(filter_top, prop_id,
+                    CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, i_val_int);
+        }
+        else if (is_i_val_null && !is_e_val_null) {
+            contacts_filter_add_int(filter_top, prop_id, CONTACTS_MATCH_LESS_THAN, e_val_int);
+        }
+        else if (!is_i_val_null && !is_e_val_null) {
+            contacts_filter_add_int(sub_filter, prop_id,
+                    CONTACTS_MATCH_GREATER_THAN_OR_EQUAL, i_val_int);
+            contacts_filter_add_operator(sub_filter, CONTACTS_FILTER_OPERATOR_AND);
+            contacts_filter_add_int(sub_filter, prop_id, CONTACTS_MATCH_LESS_THAN, e_val_int);
+            contacts_filter_add_filter(filter_top, sub_filter);
+        }
+    }
+    contacts_filter_destroy(sub_filter);
+}
+
+static void generateFilter(std::stack<contacts_filter_h>& stack,
+        const picojson::object filter,
+        CompositeTypeEnum type)
+{
+    LoggerD("Entered");
+    switch (getFilterType(filter)) {
+        case FILTER_ATTRIBUTE: {
+                visitAttribute(stack, filter);
+                if (type != NONE) {
+                    contacts_filter_h top_filter = stack.top();
+                    if (type == UNION) {
+                        contacts_filter_add_operator(top_filter, CONTACTS_FILTER_OPERATOR_OR);
+                    } else {
+                        contacts_filter_add_operator(top_filter, CONTACTS_FILTER_OPERATOR_AND);
+                    }
+                }
+            }
+            break;
+        case FILTER_ATTRIBUTE_RANGE: {
+                visitAttributeRange(stack, filter);
+                if (type != NONE) {
+                    contacts_filter_h top_filter = stack.top();
+                    if (type == UNION) {
+                        contacts_filter_add_operator(top_filter, CONTACTS_FILTER_OPERATOR_OR);
+                    } else {
+                        contacts_filter_add_operator(top_filter, CONTACTS_FILTER_OPERATOR_AND);
+                    }
+                }
+            }
+            break;
+        case FILTER_COMPOSITE: {
+                contacts_filter_h contact_filter = NULL;
+                contacts_filter_create(_contacts_phone_log._uri, &contact_filter);
+                if (contact_filter != NULL) {
+                stack.push(contact_filter);
+                }
+
+                CompositeTypeEnum composite_type = getCompositeType(filter);
+                const picojson::array& filters =
+                        filter.find("filters")->second.get<picojson::array>();
+
+                for (auto it = filters.begin(); it != filters.end(); ++it) {
+                    generateFilter(stack, it->get<picojson::object>(), composite_type);
+                }
+
+                contacts_filter_h top_filter = stack.top();
+                if (stack.size() > 1) {
+                    stack.pop();
+                    contacts_filter_h parent_filter = stack.top();
+                    contacts_filter_add_filter(parent_filter, top_filter);
+                    contacts_filter_destroy(top_filter);
+                }
+            }
+            break;
+        case FILTER_UNKNOWN:
+            return;
+            break;
+    }
+}
+
+void CallHistoryUtils::createFilter(contacts_filter_h filter, const picojson::object filter_obj)
+{
+    std::stack<contacts_filter_h> filter_stack;
+    filter_stack.push(filter);
+    generateFilter(filter_stack, filter_obj, CompositeTypeEnum::NONE);
+}
+
 } // namespace callhistory
 } // namespace extension
index 0bfa01044cb20df8bb07bf176362926831b09045..64825fc43a66ebe55c453b48071ba97d60363780 100644 (file)
@@ -20,6 +20,8 @@ public:
     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);
+    static unsigned int convertAttributeName(const std::string attribute_name);
+    static void createFilter(contacts_filter_h filter, const picojson::object filter_obj);
 };
 
 } // namespace callhistory