diff --git a/src/search/magic-search.cpp b/src/search/magic-search.cpp index 3d9c6adf4..5a6061778 100644 --- a/src/search/magic-search.cpp +++ b/src/search/magic-search.cpp @@ -121,7 +121,7 @@ list MagicSearch::getContactListFromFilter(const string &filter, c list returnList; LinphoneProxyConfig *proxy = nullptr; - if (filter.empty()) return getAllFriends(); + if (filter.empty()) return getFriends(withDomain); if (getSearchCache() != nullptr) { resultList = continueSearch(filter, withDomain); @@ -150,8 +150,10 @@ list MagicSearch::getContactListFromFilter(const string &filter, c if (domain) { string filterAddress = "sip:" + filter + "@" + domain; LinphoneAddress *lastResult = linphone_core_create_address(this->getCore()->getCCore(), filterAddress.c_str()); - if (lastResult) returnList.push_back(SearchResult(0, lastResult, "", nullptr)); - linphone_address_unref(lastResult); + if (lastResult) { + returnList.push_back(SearchResult(0, lastResult, "", nullptr)); + linphone_address_unref(lastResult); + } } } @@ -173,8 +175,33 @@ void MagicSearch::setSearchCache(list *cache) { d->mCacheResult = cache; } -list MagicSearch::getAllFriends() { +list MagicSearch::getAddressFromCallLog(const string &filter, const string &withDomain) { + list resultList; + const bctbx_list_t *callLog = linphone_core_get_call_logs(this->getCore()->getCCore()); + + // For all call log or when we reach the search limit + for (const bctbx_list_t *f = callLog ; f != nullptr ; f = bctbx_list_next(f)) { + LinphoneCallLog *log = reinterpret_cast(f->data); + const LinphoneAddress *addr = (linphone_call_log_get_dir(log) == LinphoneCallDir::LinphoneCallIncoming) ? + linphone_call_log_get_from_address(log) : linphone_call_log_get_to_address(log); + if (addr) { + if (filter.empty()) { + resultList.push_back(SearchResult(0, addr, "", nullptr)); + } else { + unsigned int weight = searchInAddress(addr, filter, withDomain); + if (weight > getMinWeight()) { + resultList.push_back(SearchResult(weight, addr, "", nullptr)); + } + } + } + } + + return resultList; +} + +list MagicSearch::getFriends(const string &withDomain) { list returnList; + list clResults; 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)) { @@ -183,17 +210,26 @@ list MagicSearch::getAllFriends() { bctbx_list_t *lPhoneNumbers = linphone_friend_get_phone_numbers(lFriend); string lPhoneNumber = (lPhoneNumbers != nullptr) ? static_cast(lPhoneNumbers->data) : ""; + if (!withDomain.empty()) { + if (!lAddress) + continue; + if (withDomain.compare("*") != 0 && withDomain.compare(linphone_address_get_domain(lAddress)) != 0) + continue; + } returnList.push_back(SearchResult(1, lAddress, lPhoneNumber, lFriend)); } + clResults = getAddressFromCallLog("", withDomain); + addResultsToResultsList(clResults, returnList); + returnList.sort([](const SearchResult& lsr, const SearchResult& rsr){ unsigned int cpt = 0; string name1 = linphone_friend_get_name(lsr.getFriend()); string name2 = linphone_friend_get_name(rsr.getFriend()); - int char1 = tolower(name1.at(cpt)); - int char2 = tolower(name2.at(cpt)); while (name1.size() > cpt && name2.size() > cpt) { + int char1 = tolower(name1.at(cpt)); + int char2 = tolower(name2.at(cpt)); if (char1 < char2) { return true; } else if (char1 > char2) { @@ -208,28 +244,18 @@ list MagicSearch::getAllFriends() { } list *MagicSearch::beginNewSearch(const string &filter, const string &withDomain) { + list clResults; list *resultList = new list(); LinphoneFriendList *fList = linphone_core_get_default_friend_list(this->getCore()->getCCore()); - const bctbx_list_t *callLog = linphone_core_get_call_logs(this->getCore()->getCCore()); // For all friends or when we reach the search limit for (bctbx_list_t *f = fList->friends ; f != nullptr ; f = bctbx_list_next(f)) { - list results = searchInFriend(reinterpret_cast(f->data), filter, withDomain); - addResultsToResultsList(results, *resultList); + list fResults = searchInFriend(reinterpret_cast(f->data), filter, withDomain); + addResultsToResultsList(fResults, *resultList); } - // For all call log or when we reach the search limit - for (const bctbx_list_t *f = callLog ; f != nullptr ; f = bctbx_list_next(f)) { - LinphoneCallLog *log = reinterpret_cast(f->data); - const LinphoneAddress *addr = (linphone_call_log_get_dir(log) == LinphoneCallDir::LinphoneCallIncoming) ? - linphone_call_log_get_from_address(log) : linphone_call_log_get_to_address(log); - if (addr) { - unsigned int weight = searchInAddress(addr, filter, withDomain); - if (weight > getMinWeight()) { - resultList->push_back(SearchResult(weight, addr, "", nullptr)); - } - } - } + clResults = getAddressFromCallLog(filter, withDomain); + addResultsToResultsList(clResults, *resultList); return resultList; } @@ -382,12 +408,12 @@ bool MagicSearch::checkDomain(const LinphoneFriend *lFriend, const LinphoneAddre } bool soFarSoGood = + !onlySipUri || ( // If we don't want Sip URI only or Address or Presence model - (!onlySipUri || lAddress || presenceModel) && + (lAddress || presenceModel) && // And If we don't want Sip URI only or Address match or Address presence match - (!onlySipUri || - (lAddress && withDomain.compare(linphone_address_get_domain(lAddress)) == 0) || - (addrPresence && withDomain.compare(linphone_address_get_domain(addrPresence)) == 0) + ((lAddress && withDomain.compare(linphone_address_get_domain(lAddress)) == 0) || + (addrPresence && withDomain.compare(linphone_address_get_domain(addrPresence)) == 0)) ); if (addrPresence) linphone_address_unref(addrPresence); diff --git a/src/search/magic-search.h b/src/search/magic-search.h index ac6a30e30..806ebc9fe 100644 --- a/src/search/magic-search.h +++ b/src/search/magic-search.h @@ -140,12 +140,22 @@ private: **/ void setSearchCache(std::list *cache); + /** + * Get all address from call log + * @param[in] filter word we search + * @param[in] withDomain domain which we want to search only + * @return all address from call log which match in a SearchResult list + * @private + **/ + std::list getAddressFromCallLog(const std::string &filter, const std::string &withDomain); + /** * Get all friends as SearchResult + * @param[in] withDomain domain which we want to search only * @return all friends in a SearchResult list * @private **/ - std::list getAllFriends(); + std::list getFriends(const std::string &withDomain); /** * Begin the search from friend list diff --git a/tester/db/friends.db b/tester/db/friends.db index 20fd191ea..6c476b645 100644 Binary files a/tester/db/friends.db and b/tester/db/friends.db differ diff --git a/tester/setup_tester.c b/tester/setup_tester.c index abf5f3fe9..221860884 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -493,21 +493,25 @@ static void search_friend_in_alphabetical_order(void) { const char *name2SipUri = {"sip:stephanie@sip.example.org"}; const char *name3SipUri = {"sip:alber@sip.example.org"}; const char *name4SipUri = {"sip:gauthier@sip.example.org"}; + const char *name5SipUri = {"sip:gal@sip.example.org"}; LinphoneFriend *friend1 = linphone_core_create_friend(manager->lc); LinphoneFriend *friend2 = linphone_core_create_friend(manager->lc); LinphoneFriend *friend3 = linphone_core_create_friend(manager->lc); LinphoneFriend *friend4 = linphone_core_create_friend(manager->lc); + LinphoneFriend *friend5 = linphone_core_create_friend(manager->lc); LinphoneVcard *vcard1 = linphone_factory_create_vcard(linphone_factory_get()); LinphoneVcard *vcard2 = linphone_factory_create_vcard(linphone_factory_get()); LinphoneVcard *vcard3 = linphone_factory_create_vcard(linphone_factory_get()); LinphoneVcard *vcard4 = linphone_factory_create_vcard(linphone_factory_get()); + LinphoneVcard *vcard5 = linphone_factory_create_vcard(linphone_factory_get()); const char *name1 = {"STEPHANIE delarue"}; const char *name2 = {"alias delarue"}; const char *name3 = {"Alber josh"}; const char *name4 = {"gauthier wei"}; + const char *name5 = {"gal tcho"}; linphone_vcard_set_full_name(vcard1, name1); // STEPHANIE delarue linphone_vcard_set_url(vcard1, name1SipUri); //sip:toto@sip.example.org @@ -533,16 +537,23 @@ static void search_friend_in_alphabetical_order(void) { linphone_friend_set_vcard(friend4, vcard4); linphone_core_add_friend(manager->lc, friend4); + linphone_vcard_set_full_name(vcard5, name5); // gal tcho + linphone_vcard_set_url(vcard5, name5SipUri); //sip:gal@sip.example.org + linphone_vcard_add_sip_address(vcard5, name5SipUri); + linphone_friend_set_vcard(friend5, vcard5); + linphone_core_add_friend(manager->lc, friend5); + magicSearch = linphone_magic_search_new(manager->lc); resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "", ""); 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, name3SipUri, NULL);//"sip:stephanie@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, name2SipUri, NULL);//"sip:alber@sip.example.org" - _check_friend_result_list(manager->lc, resultList, 2, name4SipUri, NULL);//"sip:gauthier@sip.example.org" - _check_friend_result_list(manager->lc, resultList, 3, name1SipUri, NULL);//"sip:toto@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 2, name5SipUri, NULL);//"sip:gal@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 3, name4SipUri, NULL);//"sip:gauthier@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 4, name1SipUri, NULL);//"sip:toto@sip.example.org" bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } @@ -552,16 +563,19 @@ static void search_friend_in_alphabetical_order(void) { linphone_friend_list_remove_friend(lfl, friend2); linphone_friend_list_remove_friend(lfl, friend3); linphone_friend_list_remove_friend(lfl, friend4); + linphone_friend_list_remove_friend(lfl, friend5); if (friend1) linphone_friend_unref(friend1); if (friend2) linphone_friend_unref(friend2); if (friend3) linphone_friend_unref(friend3); if (friend4) linphone_friend_unref(friend4); + if (friend5) linphone_friend_unref(friend5); if (vcard1) linphone_vcard_unref(vcard1); if (vcard2) linphone_vcard_unref(vcard2); if (vcard3) linphone_vcard_unref(vcard3); if (vcard4) linphone_vcard_unref(vcard4); + if (vcard5) linphone_vcard_unref(vcard5); linphone_magic_search_unref(magicSearch); linphone_core_manager_destroy(manager); @@ -591,6 +605,33 @@ static void search_friend_without_filter(void) { linphone_core_manager_destroy(manager); } +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); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + + _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, "", "sip.test.org"); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 4, 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" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + + linphone_magic_search_unref(magicSearch); + linphone_core_manager_destroy(manager); +} + static void search_friend_all_domains(void) { LinphoneMagicSearch *magicSearch = NULL; bctbx_list_t *resultList = NULL; @@ -1151,7 +1192,8 @@ test_t setup_tests[] = { TEST_NO_TAG("Codec setup", codec_setup), TEST_NO_TAG("Custom tones setup", custom_tones_setup), TEST_ONE_TAG("Return friend list in alphabetical order", search_friend_in_alphabetical_order, "MagicSearch"), - TEST_ONE_TAG("Search friend without filter", search_friend_without_filter, "MagicSearch"), + TEST_ONE_TAG("Search friend without filter and domain", search_friend_without_filter, "MagicSearch"), + TEST_ONE_TAG("Search friend with domain and without filter", search_friend_with_domain_without_filter, "MagicSearch"), TEST_ONE_TAG("Search friend from all domains", search_friend_all_domains, "MagicSearch"), TEST_ONE_TAG("Search friend from one domain", search_friend_one_domain, "MagicSearch"), TEST_ONE_TAG("Multiple looking for friends with the same cache", search_friend_research_estate, "MagicSearch"),