/* * Copyright (c) 2010-2019 Belledonne Communications SARL. * * This file is part of linphone-android * (see https://www.linphone.org). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package org.linphone.contacts; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; import java.util.Objects; import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.contacts.views.ContactAvatar; import org.linphone.core.Address; import org.linphone.core.Core; import org.linphone.core.FriendCapability; import org.linphone.core.PresenceBasicStatus; import org.linphone.core.PresenceModel; import org.linphone.core.ProxyConfig; import org.linphone.core.SearchResult; public class SearchContactsAdapter extends RecyclerView.Adapter { private List mContacts; private ArrayList mContactsSelected; private boolean mOnlySipContact = false; private final SearchContactViewHolder.ClickListener mListener; private final boolean mIsOnlyOnePersonSelection; private String mPreviousSearch; private boolean mSecurityEnabled; public SearchContactsAdapter( SearchContactViewHolder.ClickListener clickListener, boolean hideSelectionMark, boolean isSecurityEnabled) { mIsOnlyOnePersonSelection = hideSelectionMark; mListener = clickListener; setContactsSelectedList(null); mPreviousSearch = null; mSecurityEnabled = isSecurityEnabled; mContacts = new ArrayList<>(); } public List getContacts() { return mContacts; } public void setOnlySipContact(boolean enable) { mOnlySipContact = enable; } public void setSecurityEnabled(boolean enable) { mSecurityEnabled = enable; notifyDataSetChanged(); } @NonNull @Override public SearchContactViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.search_contact_cell, parent, false); return new SearchContactViewHolder(v, mListener); } @Override public void onBindViewHolder(@NonNull SearchContactViewHolder holder, int position) { SearchResult searchResult = getItem(position); LinphoneContact contact; if (searchResult.getFriend() != null && searchResult.getFriend().getUserData() != null) { contact = (LinphoneContact) searchResult.getFriend().getUserData(); } else { if (searchResult.getAddress() == null) { contact = ContactsManager.getInstance() .findContactFromPhoneNumber(searchResult.getPhoneNumber()); } else { contact = ContactsManager.getInstance() .findContactFromAddress(searchResult.getAddress()); } } final String numberOrAddress = (searchResult.getPhoneNumber() != null) ? searchResult.getPhoneNumber() : searchResult.getAddress().asStringUriOnly(); holder.name.setVisibility(View.GONE); if (contact != null && contact.getFullName() != null) { holder.name.setVisibility(View.VISIBLE); holder.name.setText(contact.getFullName()); } else if (searchResult.getAddress() != null) { if (searchResult.getAddress().getUsername() != null) { holder.name.setVisibility(View.VISIBLE); holder.name.setText(searchResult.getAddress().getUsername()); } else if (searchResult.getAddress().getDisplayName() != null) { holder.name.setVisibility(View.VISIBLE); holder.name.setText(searchResult.getAddress().getDisplayName()); } } holder.disabled.setVisibility(View.GONE); if (mSecurityEnabled || !mIsOnlyOnePersonSelection) { Core core = LinphoneManager.getCore(); ProxyConfig defaultProxyConfig = core.getDefaultProxyConfig(); if (defaultProxyConfig != null && searchResult.getAddress() != null) { // SDK won't accept ourselves in the list of participants if (defaultProxyConfig.getIdentityAddress().weakEqual(searchResult.getAddress())) { // Disable row, we can't use our own address in a group chat room holder.disabled.setVisibility(View.VISIBLE); } } } if (contact != null) { if (contact.getFullName() == null && contact.getFirstName() == null && contact.getLastName() == null) { contact.setFullName(holder.name.getText().toString()); } ContactAvatar.displayAvatar( contact, contact.hasFriendCapability(FriendCapability.LimeX3Dh), holder.avatarLayout); if ((!mIsOnlyOnePersonSelection && !searchResult.hasCapability(FriendCapability.GroupChat)) || (mSecurityEnabled && !searchResult.hasCapability(FriendCapability.LimeX3Dh))) { // Disable row, contact doesn't have the required capabilities holder.disabled.setVisibility(View.VISIBLE); } } else { ContactAvatar.displayAvatar(holder.name.getText().toString(), holder.avatarLayout); } holder.address.setText(numberOrAddress); if (holder.linphoneContact != null) { holder.linphoneContact.setVisibility(View.GONE); if (searchResult.getFriend() != null && contact != null && contact.getBasicStatusFromPresenceModelForUriOrTel(numberOrAddress) == PresenceBasicStatus.Open) { holder.linphoneContact.setVisibility(View.VISIBLE); } } if (holder.isSelect != null) { if (isContactSelected(searchResult)) { holder.isSelect.setVisibility(View.VISIBLE); } else { holder.isSelect.setVisibility(View.INVISIBLE); } if (mIsOnlyOnePersonSelection) { holder.isSelect.setVisibility(View.GONE); } } } public long getItemId(int position) { return position; } private synchronized boolean isContactSelected(SearchResult sr) { for (ContactAddress c : mContactsSelected) { Address addr = c.getAddress(); if (addr != null && sr.getAddress() != null) { if (addr.weakEqual(sr.getAddress())) { return true; } } else { if (c.getPhoneNumber() != null && sr.getPhoneNumber() != null) { if (c.getPhoneNumber().compareTo(sr.getPhoneNumber()) == 0) return true; } } } return false; } public synchronized ArrayList getContactsSelectedList() { return mContactsSelected; } public synchronized void setContactsSelectedList(ArrayList contactsList) { if (contactsList == null) { mContactsSelected = new ArrayList<>(); } else { mContactsSelected = contactsList; } } public synchronized boolean toggleContactSelection(ContactAddress ca) { if (mContactsSelected.contains(ca)) { mContactsSelected.remove(ca); return false; } else { mContactsSelected.add(ca); return true; } } private SearchResult getItem(int position) { return mContacts.get(position); } @Override public int getItemCount() { return mContacts.size(); } public void searchContacts(String search) { List result = new ArrayList<>(); if (mPreviousSearch != null) { if (mPreviousSearch.length() > search.length()) { ContactsManager.getInstance().getMagicSearch().resetSearchCache(); } } mPreviousSearch = search; String domain = ""; ProxyConfig prx = Objects.requireNonNull(LinphoneManager.getCore()).getDefaultProxyConfig(); if (prx != null) domain = prx.getDomain(); SearchResult[] searchResults = ContactsManager.getInstance() .getMagicSearch() .getContactListFromFilter(search, mOnlySipContact ? domain : ""); for (SearchResult sr : searchResults) { if (LinphoneContext.instance() .getApplicationContext() .getResources() .getBoolean(R.bool.hide_sip_contacts_without_presence)) { if (sr.getFriend() != null) { PresenceModel pm = sr.getFriend() .getPresenceModelForUriOrTel(sr.getAddress().asStringUriOnly()); if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { result.add(sr); } else { pm = sr.getFriend().getPresenceModelForUriOrTel(sr.getPhoneNumber()); if (pm != null && pm.getBasicStatus().equals(PresenceBasicStatus.Open)) { result.add(sr); } } } } else { result.add(sr); } } mContacts = result; notifyDataSetChanged(); } }