diff --git a/src/search/magic-search.cpp b/src/search/magic-search.cpp index 2d5e7599c..fafa4841b 100644 --- a/src/search/magic-search.cpp +++ b/src/search/magic-search.cpp @@ -148,7 +148,9 @@ list MagicSearch::getContactListFromFilter(const string &filter, c if (proxy) { const char *domain = linphone_proxy_config_get_domain(proxy); if (domain) { - string filterAddress = "sip:" + filter + "@" + domain; + string strTmp = filter; + transform(strTmp.begin(), strTmp.end(), strTmp.begin(), [](unsigned char c){ return tolower(c); }); + string filterAddress = "sip:" + strTmp + "@" + domain; LinphoneAddress *lastResult = linphone_core_create_address(this->getCore()->getCCore(), filterAddress.c_str()); if (lastResult) { returnList.push_back(SearchResult(0, lastResult, "", nullptr)); @@ -175,7 +177,27 @@ void MagicSearch::setSearchCache(list *cache) { d->mCacheResult = cache; } -list MagicSearch::getAddressFromCallLog(const string &filter, const string &withDomain) { +static bool findAddress(const list &list, const LinphoneAddress *addr) { + bool returnValue = false; + char *charAddr = linphone_address_as_string_uri_only(addr); + string sAddr = charAddr; + for (auto r : list) { + if (r.getAddress()) { + char *charTmp = linphone_address_as_string_uri_only(r.getAddress()); + string tmp = charTmp; + if (sAddr == tmp){ + returnValue = true; + if (charTmp) bctbx_free(charTmp); + break; + } + if (charTmp) bctbx_free(charTmp); + } + } + if (charAddr) bctbx_free(charAddr); + return returnValue; +} + +list MagicSearch::getAddressFromCallLog(const string &filter, const string &withDomain, const list ¤tList) { list resultList; const bctbx_list_t *callLog = linphone_core_get_call_logs(this->getCore()->getCCore()); @@ -186,10 +208,12 @@ list MagicSearch::getAddressFromCallLog(const string &filter, cons linphone_call_log_get_from_address(log) : linphone_call_log_get_to_address(log); if (addr) { if (filter.empty()) { + if (findAddress(currentList, addr)) continue; resultList.push_back(SearchResult(0, addr, "", nullptr)); } else { unsigned int weight = searchInAddress(addr, filter, withDomain); if (weight > getMinWeight()) { + if (findAddress(currentList, addr)) continue; resultList.push_back(SearchResult(weight, addr, "", nullptr)); } } @@ -205,21 +229,37 @@ list MagicSearch::getFriends(const string &withDomain) { LinphoneFriendList *list = linphone_core_get_default_friend_list(this->getCore()->getCCore()); for (bctbx_list_t *f = list->friends ; f != nullptr ; f = bctbx_list_next(f)) { + LinphoneAddress *phoneAddress = nullptr; const LinphoneFriend *lFriend = reinterpret_cast(f->data); - const LinphoneAddress* lAddress = linphone_friend_get_address(lFriend); + const LinphoneAddress *lAddress = linphone_friend_get_address(lFriend); bctbx_list_t *lPhoneNumbers = linphone_friend_get_phone_numbers(lFriend); string lPhoneNumber = (lPhoneNumbers != nullptr) ? static_cast(lPhoneNumbers->data) : ""; + const LinphonePresenceModel *presence = linphone_friend_get_presence_model(lFriend); + if (lPhoneNumbers) bctbx_list_free(lPhoneNumbers); + + if (presence && !lAddress) { + char *contact = linphone_presence_model_get_contact(presence); + if (contact) { + phoneAddress = linphone_core_create_address(this->getCore()->getCCore(), contact); + bctbx_free(contact); + } + } if (!withDomain.empty()) { - if (!lAddress) + if (!lAddress && !phoneAddress) continue; - if (withDomain != "*" && withDomain != linphone_address_get_domain(lAddress)) + if (withDomain != "*" && + withDomain != ((lAddress) ? linphone_address_get_domain(lAddress) : "") && + withDomain != ((phoneAddress) ? linphone_address_get_domain(phoneAddress) : "")) continue; } + + if (phoneAddress) linphone_address_unref(phoneAddress); + returnList.push_back(SearchResult(1, lAddress, lPhoneNumber, lFriend)); } - clResults = getAddressFromCallLog("", withDomain); + clResults = getAddressFromCallLog("", withDomain, clResults); addResultsToResultsList(clResults, returnList); returnList.sort([](const SearchResult& lsr, const SearchResult& rsr){ @@ -267,7 +307,7 @@ list *MagicSearch::beginNewSearch(const string &filter, const stri addResultsToResultsList(fResults, *resultList); } - clResults = getAddressFromCallLog(filter, withDomain); + clResults = getAddressFromCallLog(filter, withDomain, *resultList); addResultsToResultsList(clResults, *resultList); return uniqueItemsList(*resultList); @@ -469,13 +509,17 @@ list *MagicSearch::uniqueItemsList(list &list) { if (contactPresence) { addrPresence = linphone_core_create_address(lc, contactPresence); if (addrPresence) { - left = linphone_address_as_string_uri_only(addrPresence); + char *tmp = linphone_address_as_string_uri_only(addrPresence); + left = tmp; + if (tmp) bctbx_free(tmp); linphone_address_unref(addrPresence); } bctbx_free(contactPresence); } } else { - left = linphone_address_as_string_uri_only(lsr.getAddress()); + char *tmp = linphone_address_as_string_uri_only(lsr.getAddress()); + left = tmp; + if (tmp) bctbx_free(tmp); } if (!rsr.getAddress() && rsr.getFriend()) { @@ -486,13 +530,17 @@ list *MagicSearch::uniqueItemsList(list &list) { if (contactPresence) { addrPresence = linphone_core_create_address(lc, contactPresence); if (addrPresence) { - right = linphone_address_as_string_uri_only(addrPresence); + char *tmp = linphone_address_as_string_uri_only(addrPresence); + right = tmp; + if (tmp) bctbx_free(tmp); linphone_address_unref(addrPresence); } bctbx_free(contactPresence); } } else { - right = linphone_address_as_string_uri_only(rsr.getAddress()); + char *tmp = linphone_address_as_string_uri_only(rsr.getAddress()); + right = tmp; + if (tmp) bctbx_free(tmp); } return (!left.empty() || !right.empty()) && left == right; diff --git a/src/search/magic-search.h b/src/search/magic-search.h index e30a99345..13348bac0 100644 --- a/src/search/magic-search.h +++ b/src/search/magic-search.h @@ -144,10 +144,11 @@ private: * Get all address from call log * @param[in] filter word we search * @param[in] withDomain domain which we want to search only + * @param[in] currentList current list where we will check if address already exist * @return all address from call log which match in a SearchResult list * @private **/ - std::list getAddressFromCallLog(const std::string &filter, const std::string &withDomain); + std::list getAddressFromCallLog(const std::string &filter, const std::string &withDomain, const std::list ¤tList); /** * Get all friends as SearchResult diff --git a/tester/setup_tester.c b/tester/setup_tester.c index 419614ed0..75b51c2f7 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -608,8 +608,25 @@ static void search_friend_without_filter(void) { static void search_friend_with_domain_without_filter(void) { LinphoneMagicSearch *magicSearch = NULL; bctbx_list_t *resultList = NULL; - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneCoreManager* manager = linphone_core_manager_new2("marie_rc", FALSE); LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const char *chloeName = "chloe zaya"; + const char *chloeSipUri = "sip:ch@sip.test.org"; + const char *chloePhoneNumber = "0633556644"; + LinphoneFriend *chloeFriend = linphone_core_create_friend(manager->lc); + LinphonePresenceModel *chloePresence = linphone_core_create_presence_model(manager->lc); + LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(manager->lc); + + linphone_proxy_config_edit(proxy); + linphone_proxy_config_set_dial_prefix(proxy, "33"); + linphone_proxy_config_done(proxy); + linphone_core_set_default_proxy(manager->lc, proxy); + + linphone_presence_model_set_contact(chloePresence, chloeSipUri); + linphone_friend_set_name(chloeFriend, chloeName); + linphone_friend_add_phone_number(chloeFriend, chloePhoneNumber); + linphone_friend_set_presence_model_for_uri_or_tel(chloeFriend, chloePhoneNumber, chloePresence); + linphone_friend_list_add_friend(lfl, chloeFriend); _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); @@ -618,16 +635,22 @@ static void search_friend_with_domain_without_filter(void) { resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "", "sip.test.org"); if (BC_ASSERT_PTR_NOT_NULL(resultList)) { - BC_ASSERT_EQUAL(bctbx_list_size(resultList), 4, int, "%d"); + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 5, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, sFriends[0], NULL);//"sip:charu@sip.test.org" - _check_friend_result_list(manager->lc, resultList, 1, sFriends[4], NULL);//"sip:hello@sip.test.org" - _check_friend_result_list(manager->lc, resultList, 2, sFriends[8], NULL);//"sip:laure@sip.test.org" - _check_friend_result_list(manager->lc, resultList, 3, sFriends[9], NULL);//"sip:loic@sip.test.org" + _check_friend_result_list(manager->lc, resultList, 1, chloeSipUri, chloePhoneNumber);//"sip:ch@sip.test.org" + _check_friend_result_list(manager->lc, resultList, 2, sFriends[4], NULL);//"sip:hello@sip.test.org" + _check_friend_result_list(manager->lc, resultList, 3, sFriends[8], NULL);//"sip:laure@sip.test.org" + _check_friend_result_list(manager->lc, resultList, 4, sFriends[9], NULL);//"sip:loic@sip.test.org" bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); + LinphoneFriend *fr = linphone_friend_list_find_friend_by_uri(lfl, chloeSipUri); + linphone_friend_list_remove_friend(lfl, fr); + + if (chloeFriend) linphone_friend_unref(chloeFriend); + linphone_magic_search_unref(magicSearch); linphone_core_manager_destroy(manager); } @@ -969,6 +992,46 @@ static void search_friend_in_call_log(void) { linphone_core_manager_destroy(manager); } +static void search_friend_in_call_log_already_exist(void) { + LinphoneMagicSearch *magicSearch = NULL; + bctbx_list_t *resultList = NULL; + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const char *laureSipUri = {"sip:laure@sip.test.org"}; + const char *ronanSipUri = {"sip:ronan@sip.example.org"}; + + LinphoneAddress *laureAddress = linphone_address_new(laureSipUri); + LinphoneAddress *ronanAddress = linphone_address_new(ronanSipUri); + + _create_call_log(manager->lc, ronanAddress, laureAddress); + + _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); + + magicSearch = linphone_magic_search_new(manager->lc); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "laur", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, sFriends[6], NULL);//"sip:laura@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, laureSipUri, NULL);//"sip:laure@sip.test.org" + const LinphoneSearchResult *sr = bctbx_list_nth_data(resultList, 1); + if (BC_ASSERT_PTR_NOT_NULL(sr)) { + const LinphoneFriend *lf = linphone_search_result_get_friend(sr); + BC_ASSERT_PTR_NOT_NULL(lf); + } + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + + if (laureAddress) linphone_address_unref(laureAddress); + if (ronanAddress) linphone_address_unref(ronanAddress); + + linphone_magic_search_unref(magicSearch); + linphone_core_manager_destroy(manager); +} + static void search_friend_last_item_is_filter(void) { LinphoneMagicSearch *magicSearch = NULL; bctbx_list_t *resultList = NULL; @@ -1211,6 +1274,24 @@ static void search_friend_with_same_address(void) { bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } + linphone_magic_search_reset_search_cache(magicSearch); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), S_SIZE_FRIEND+1, int, "%d"); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + linphone_magic_search_reset_search_cache(magicSearch); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "", "*"); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), S_SIZE_FRIEND+1, int, "%d"); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + _remove_friends_from_list(lfl, sFriends, sSizeFriend); linphone_friend_list_remove_friend(lfl, stephanieFriend1); linphone_friend_list_remove_friend(lfl, stephanieFriend2); @@ -1238,9 +1319,11 @@ static void search_friend_large_database(void) { liblinphone_tester_clock_start(&start); bctbx_list_t *resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, subBuff, ""); if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + long long time; ms_get_cur_time(¤t); - ms_message("Searching time: %lld ms", - ((current.tv_sec - start.tv_sec) * 1000LL) + ((current.tv_nsec - start.tv_nsec) / 1000000LL)); + time = ((current.tv_sec - start.tv_sec) * 1000LL) + ((current.tv_nsec - start.tv_nsec) / 1000000LL); + ms_message("Searching time: %lld ms", time); + BC_ASSERT_LOWER(time, 10000, long long, "%lld"); ms_message("List size: %zu", bctbx_list_size(resultList)); bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } @@ -1278,6 +1361,7 @@ test_t setup_tests[] = { TEST_ONE_TAG("Search friend with phone number", search_friend_with_phone_number, "MagicSearch"), TEST_ONE_TAG("Search friend and find it with its presence", search_friend_with_presence, "MagicSearch"), TEST_ONE_TAG("Search friend in call log", search_friend_in_call_log, "MagicSearch"), + TEST_ONE_TAG("Search friend in call log but don't add address which already exist", search_friend_in_call_log_already_exist, "MagicSearch"), TEST_ONE_TAG("Search friend last item is the filter", search_friend_last_item_is_filter, "MagicSearch"), TEST_ONE_TAG("Search friend with name", search_friend_with_name, "MagicSearch"), TEST_ONE_TAG("Search friend with uppercase name", search_friend_with_name_with_uppercase, "MagicSearch"),