From 5f941004f5006b286690df2a93bc47ace3b59270 Mon Sep 17 00:00:00 2001 From: AsamK Date: Fri, 20 May 2022 11:46:03 +0200 Subject: [PATCH] Extend listContacts command with profiles and filtering --- graalvm-config-dir/reflect-config.json | 25 ++++++ graalvm-config-dir/resource-config.json | 3 + .../org/asamk/signal/manager/Manager.java | 10 ++- .../org/asamk/signal/manager/ManagerImpl.java | 53 +++++++------ .../signal/manager/helper/ProfileHelper.java | 16 +++- .../manager/helper/RecipientHelper.java | 4 +- .../signal/manager/helper/SendHelper.java | 2 +- .../storage/recipients/RecipientStore.java | 18 +++++ .../signal/commands/ListContactsCommand.java | 79 ++++++++++++++++--- .../asamk/signal/dbus/DbusManagerImpl.java | 29 +++++-- .../org/asamk/signal/dbus/DbusSignalImpl.java | 38 ++------- 11 files changed, 195 insertions(+), 82 deletions(-) diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index f9fe367f..69b19703 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -527,6 +527,20 @@ "allDeclaredMethods":true, "allDeclaredConstructors":true }, +{ + "name":"org.asamk.signal.commands.ListContactsCommand$JsonContact$JsonProfile", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"about","parameterTypes":[] }, + {"name":"aboutEmoji","parameterTypes":[] }, + {"name":"familyName","parameterTypes":[] }, + {"name":"givenName","parameterTypes":[] }, + {"name":"lastUpdateTimestamp","parameterTypes":[] }, + {"name":"paymentAddress","parameterTypes":[] } + ] +}, { "name":"org.asamk.signal.commands.ListDevicesCommand$JsonDevice", "allDeclaredFields":true, @@ -1797,6 +1811,17 @@ {"name":"userId_"} ] }, +{ + "name":"org.signal.storageservice.protos.groups.GroupChanges", + "fields":[{"name":"groupChanges_"}] +}, +{ + "name":"org.signal.storageservice.protos.groups.GroupChanges$GroupChangeState", + "fields":[ + {"name":"groupChange_"}, + {"name":"groupState_"} + ] +}, { "name":"org.signal.storageservice.protos.groups.GroupInviteLink", "fields":[ diff --git a/graalvm-config-dir/resource-config.json b/graalvm-config-dir/resource-config.json index 08a9dcc5..542c8f31 100644 --- a/graalvm-config-dir/resource-config.json +++ b/graalvm-config-dir/resource-config.json @@ -73,6 +73,9 @@ { "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE\\E" }, + { + "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK\\E" + }, { "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC\\E" }, diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index 8f49126f..cc3ce0ce 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -28,9 +28,8 @@ import org.asamk.signal.manager.groups.GroupNotFoundException; import org.asamk.signal.manager.groups.GroupSendingNotAllowedException; import org.asamk.signal.manager.groups.LastGroupAdminException; import org.asamk.signal.manager.groups.NotAGroupMemberException; -import org.asamk.signal.manager.storage.recipients.Contact; import org.asamk.signal.manager.storage.recipients.Profile; -import org.asamk.signal.manager.storage.recipients.RecipientAddress; +import org.asamk.signal.manager.storage.recipients.Recipient; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import java.io.Closeable; @@ -215,7 +214,12 @@ public interface Manager extends Closeable { void sendContacts() throws IOException; - List> getContacts(); + List getRecipients( + boolean onlyContacts, + Optional blocked, + Collection address, + Optional name + ); String getContactOrProfileName(RecipientIdentifier.Single recipient); diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index b3e6a0ae..f2d080fd 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -51,9 +51,8 @@ import org.asamk.signal.manager.helper.Context; import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.groups.GroupInfo; import org.asamk.signal.manager.storage.identities.IdentityInfo; -import org.asamk.signal.manager.storage.recipients.Contact; import org.asamk.signal.manager.storage.recipients.Profile; -import org.asamk.signal.manager.storage.recipients.RecipientAddress; +import org.asamk.signal.manager.storage.recipients.Recipient; import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack; import org.asamk.signal.manager.storage.stickerPacks.StickerPackStore; @@ -84,6 +83,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -101,7 +101,6 @@ class ManagerImpl implements Manager { private final static Logger logger = LoggerFactory.getLogger(ManagerImpl.class); private SignalAccount account; - private AccountFileUpdater accountFileUpdater; private final SignalDependencies dependencies; private final Context context; @@ -123,7 +122,6 @@ class ManagerImpl implements Manager { String userAgent ) { this.account = account; - this.accountFileUpdater = accountFileUpdater; final var sessionLock = new SignalSessionLock() { private final ReentrantLock LEGACY_LOCK = new ReentrantLock(); @@ -337,7 +335,7 @@ class ManagerImpl implements Manager { } @Override - public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException { + public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException { return context.getProfileHelper().getRecipientProfile(context.getRecipientHelper().resolveRecipient(recipient)); } @@ -495,7 +493,7 @@ class ManagerImpl implements Manager { @Override public SendMessageResults sendReadReceipt( RecipientIdentifier.Single sender, List messageIds - ) throws IOException { + ) { final var timestamp = System.currentTimeMillis(); var receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.READ, messageIds, @@ -507,7 +505,7 @@ class ManagerImpl implements Manager { @Override public SendMessageResults sendViewedReceipt( RecipientIdentifier.Single sender, List messageIds - ) throws IOException { + ) { final var timestamp = System.currentTimeMillis(); var receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.VIEWED, messageIds, @@ -520,7 +518,7 @@ class ManagerImpl implements Manager { final RecipientIdentifier.Single sender, final long timestamp, final SignalServiceReceiptMessage receiptMessage - ) throws IOException { + ) { try { final var result = context.getSendHelper() .sendReceiptMessage(receiptMessage, context.getRecipientHelper().resolveRecipient(sender)); @@ -592,7 +590,7 @@ class ManagerImpl implements Manager { } } - private ArrayList resolveMentions(final List mentionList) throws IOException, UnregisteredRecipientException { + private ArrayList resolveMentions(final List mentionList) throws UnregisteredRecipientException { final var mentions = new ArrayList(); for (final var m : mentionList) { final var recipientId = context.getRecipientHelper().resolveRecipient(m.recipient()); @@ -676,7 +674,7 @@ class ManagerImpl implements Manager { @Override public void setContactName( RecipientIdentifier.Single recipient, String name - ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException { + ) throws NotMasterDeviceException, UnregisteredRecipientException { if (!account.isMasterDevice()) { throw new NotMasterDeviceException(); } @@ -932,7 +930,7 @@ class ManagerImpl implements Manager { final RecipientId recipientId; try { recipientId = context.getRecipientHelper().resolveRecipient(recipient); - } catch (IOException | UnregisteredRecipientException e) { + } catch (UnregisteredRecipientException e) { return false; } return context.getContactHelper().isContactBlocked(recipientId); @@ -944,12 +942,22 @@ class ManagerImpl implements Manager { } @Override - public List> getContacts() { - return account.getContactStore() - .getContacts() - .stream() - .map(p -> new Pair<>(account.getRecipientStore().resolveRecipientAddress(p.first()), p.second())) - .toList(); + public List getRecipients( + boolean onlyContacts, + Optional blocked, + Collection recipients, + Optional name + ) { + final var recipientIds = recipients.stream().map(a -> { + try { + return context.getRecipientHelper().resolveRecipient(a); + } catch (UnregisteredRecipientException e) { + return null; + } + }).filter(Objects::nonNull).collect(Collectors.toSet()); + // refresh profiles of explicitly given recipients + context.getProfileHelper().refreshRecipientProfiles(recipientIds); + return account.getRecipientStore().getRecipients(onlyContacts, blocked, recipientIds, name); } @Override @@ -957,7 +965,7 @@ class ManagerImpl implements Manager { final RecipientId recipientId; try { recipientId = context.getRecipientHelper().resolveRecipient(recipient); - } catch (IOException | UnregisteredRecipientException e) { + } catch (UnregisteredRecipientException e) { return null; } @@ -1007,7 +1015,7 @@ class ManagerImpl implements Manager { try { identity = account.getIdentityKeyStore() .getIdentity(context.getRecipientHelper().resolveRecipient(recipient)); - } catch (IOException | UnregisteredRecipientException e) { + } catch (UnregisteredRecipientException e) { identity = null; } return identity == null ? List.of() : List.of(toIdentity(identity)); @@ -1044,12 +1052,7 @@ class ManagerImpl implements Manager { private boolean trustIdentity( RecipientIdentifier.Single recipient, Function trustMethod ) throws UnregisteredRecipientException { - RecipientId recipientId; - try { - recipientId = context.getRecipientHelper().resolveRecipient(recipient); - } catch (IOException e) { - return false; - } + final var recipientId = context.getRecipientHelper().resolveRecipient(recipient); final var updated = trustMethod.apply(recipientId); if (updated && this.isReceiving()) { context.getReceiveHelper().setNeedsToRetryFailedMessages(true); diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java index 4bc00317..8a64c8b7 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java @@ -36,6 +36,7 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.file.Files; import java.util.Base64; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Locale; @@ -94,10 +95,18 @@ public final class ProfileHelper { return getRecipientProfile(recipientId, false); } + public List getRecipientProfiles(Collection recipientIds) { + return getRecipientProfiles(recipientIds, false); + } + public void refreshRecipientProfile(RecipientId recipientId) { getRecipientProfile(recipientId, true); } + public void refreshRecipientProfiles(Collection recipientIds) { + getRecipientProfiles(recipientIds, true); + } + public List getRecipientProfileKeyCredential(List recipientIds) { try { account.getRecipientStore().setBulkUpdating(true); @@ -216,11 +225,12 @@ public final class ProfileHelper { return getRecipientProfile(account.getSelfRecipientId()); } - public List getRecipientProfile(List recipientIds) { + private List getRecipientProfiles(Collection recipientIds, boolean force) { + final var profileStore = account.getProfileStore(); try { account.getRecipientStore().setBulkUpdating(true); final var profileFetches = Flowable.fromIterable(recipientIds) - .filter(recipientId -> isProfileRefreshRequired(account.getProfileStore().getProfile(recipientId))) + .filter(recipientId -> force || isProfileRefreshRequired(profileStore.getProfile(recipientId))) .map(recipientId -> retrieveProfile(recipientId, SignalServiceProfile.RequestType.PROFILE).onErrorComplete()); Maybe.merge(profileFetches, 10).blockingSubscribe(); @@ -228,7 +238,7 @@ public final class ProfileHelper { account.getRecipientStore().setBulkUpdating(false); } - return recipientIds.stream().map(r -> account.getProfileStore().getProfile(r)).toList(); + return recipientIds.stream().map(profileStore::getProfile).toList(); } private Profile getRecipientProfile(RecipientId recipientId, boolean force) { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java index 15508cd4..c253d602 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java @@ -69,7 +69,7 @@ public class RecipientHelper { return account.getRecipientStore().resolveRecipient(address); } - public Set resolveRecipients(Collection recipients) throws IOException, UnregisteredRecipientException { + public Set resolveRecipients(Collection recipients) throws UnregisteredRecipientException { final var recipientIds = new HashSet(recipients.size()); for (var number : recipients) { final var recipientId = resolveRecipient(number); @@ -78,7 +78,7 @@ public class RecipientHelper { return recipientIds; } - public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException { + public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws UnregisteredRecipientException { if (recipient instanceof RecipientIdentifier.Uuid uuidRecipient) { return account.getRecipientStore().resolveRecipient(ServiceId.from(uuidRecipient.uuid())); } else { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java index a2e2379b..8b2a054e 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java @@ -475,7 +475,7 @@ public class SendHelper { final var senderKeyTargets = new HashSet(); final var recipientList = new ArrayList<>(recipientIds); - final var profiles = context.getProfileHelper().getRecipientProfile(recipientList).iterator(); + final var profiles = context.getProfileHelper().getRecipientProfiles(recipientList).iterator(); for (final var recipientId : recipientList) { final var profile = profiles.next(); if (profile == null || !profile.getCapabilities().contains(Profile.Capability.senderKey)) { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java index 299a3980..850b6270 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java @@ -277,6 +277,24 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile .toList(); } + public List getRecipients( + boolean onlyContacts, Optional blocked, Set recipientIds, Optional name + ) { + return recipients.values() + .stream() + .filter(r -> !onlyContacts || r.getContact() != null) + .filter(r -> blocked.isEmpty() || ( + blocked.get() == ( + r.getContact() != null && r.getContact().isBlocked() + ) + )) + .filter(r -> recipientIds.isEmpty() || (recipientIds.contains(r.getRecipientId()))) + .filter(r -> name.isEmpty() + || (r.getContact() != null && name.get().equals(r.getContact().getName())) + || (r.getProfile() != null && name.get().equals(r.getProfile().getDisplayName()))) + .toList(); + } + @Override public void deleteContact(RecipientId recipientId) { synchronized (recipients) { diff --git a/src/main/java/org/asamk/signal/commands/ListContactsCommand.java b/src/main/java/org/asamk/signal/commands/ListContactsCommand.java index b83440ec..0bfc7ab9 100644 --- a/src/main/java/org/asamk/signal/commands/ListContactsCommand.java +++ b/src/main/java/org/asamk/signal/commands/ListContactsCommand.java @@ -1,13 +1,20 @@ package org.asamk.signal.commands; +import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; +import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.manager.Manager; +import org.asamk.signal.manager.storage.recipients.Contact; +import org.asamk.signal.manager.storage.recipients.Profile; import org.asamk.signal.output.JsonWriter; import org.asamk.signal.output.OutputWriter; import org.asamk.signal.output.PlainTextWriter; +import org.asamk.signal.util.CommandUtil; +import java.util.Base64; +import java.util.Optional; import java.util.UUID; public class ListContactsCommand implements JsonRpcLocalCommand { @@ -19,19 +26,39 @@ public class ListContactsCommand implements JsonRpcLocalCommand { @Override public void attachToSubparser(final Subparser subparser) { - subparser.help("Show a list of known contacts with names."); + subparser.help("Show a list of known contacts with names and profiles."); + subparser.addArgument("recipient").help("Specify one ore more phone numbers to show.").nargs("*"); + subparser.addArgument("-a", "--all-recipients") + .action(Arguments.storeTrue()) + .help("Include all known recipients, not only contacts."); + subparser.addArgument("--blocked") + .type(Boolean.class) + .help("Specify if only blocked or unblocked contacts should be shown (default: all contacts)"); + subparser.addArgument("--name").help("Find contacts with the given contact or profile name."); } @Override - public void handleCommand(final Namespace ns, final Manager m, final OutputWriter outputWriter) { - var contacts = m.getContacts(); + public void handleCommand( + final Namespace ns, final Manager m, final OutputWriter outputWriter + ) throws CommandException { + final var allRecipients = Boolean.TRUE.equals(ns.getBoolean("all-recipients")); + final var blocked = ns.getBoolean("blocked"); + final var recipientStrings = ns.getList("recipient"); + final var recipientIdentifiers = CommandUtil.getSingleRecipientIdentifiers(recipientStrings, m.getSelfNumber()); + final var name = ns.getString("name"); + final var recipients = m.getRecipients(!allRecipients, + Optional.ofNullable(blocked), + recipientIdentifiers, + Optional.ofNullable(name)); if (outputWriter instanceof PlainTextWriter writer) { - for (var c : contacts) { - final var contact = c.second(); - writer.println("Number: {} Name: {} Blocked: {} Message expiration: {}", - c.first().getLegacyIdentifier(), + for (var r : recipients) { + final var contact = r.getContact() == null ? Contact.newBuilder().build() : r.getContact(); + final var profile = r.getProfile() == null ? Profile.newBuilder().build() : r.getProfile(); + writer.println("Number: {} Name: {} Profile name: {} Blocked: {} Message expiration: {}", + r.getAddress().getLegacyIdentifier(), contact.getName(), + profile.getDisplayName(), contact.isBlocked(), contact.getMessageExpirationTime() == 0 ? "disabled" @@ -39,19 +66,47 @@ public class ListContactsCommand implements JsonRpcLocalCommand { } } else { final var writer = (JsonWriter) outputWriter; - final var jsonContacts = contacts.stream().map(contactPair -> { - final var address = contactPair.first(); - final var contact = contactPair.second(); + final var jsonContacts = recipients.stream().map(r -> { + final var address = r.getAddress(); + final var contact = r.getContact() == null ? Contact.newBuilder().build() : r.getContact(); return new JsonContact(address.number().orElse(null), address.uuid().map(UUID::toString).orElse(null), contact.getName(), contact.isBlocked(), - contact.getMessageExpirationTime()); + contact.getMessageExpirationTime(), + r.getProfile() == null + ? null + : new JsonContact.JsonProfile(r.getProfile().getLastUpdateTimestamp(), + r.getProfile().getGivenName(), + r.getProfile().getFamilyName(), + r.getProfile().getAbout(), + r.getProfile().getAboutEmoji(), + r.getProfile().getPaymentAddress() == null + ? null + : Base64.getEncoder() + .encodeToString(r.getProfile().getPaymentAddress()))); }).toList(); writer.write(jsonContacts); } } - private record JsonContact(String number, String uuid, String name, boolean isBlocked, int messageExpirationTime) {} + private record JsonContact( + String number, + String uuid, + String name, + boolean isBlocked, + int messageExpirationTime, + JsonProfile profile + ) { + + private record JsonProfile( + long lastUpdateTimestamp, + String givenName, + String familyName, + String about, + String aboutEmoji, + String paymentAddress + ) {} + } } diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index 5b33b039..11800be2 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -32,6 +32,7 @@ import org.asamk.signal.manager.groups.LastGroupAdminException; import org.asamk.signal.manager.groups.NotAGroupMemberException; import org.asamk.signal.manager.storage.recipients.Contact; import org.asamk.signal.manager.storage.recipients.Profile; +import org.asamk.signal.manager.storage.recipients.Recipient; import org.asamk.signal.manager.storage.recipients.RecipientAddress; import org.freedesktop.dbus.DBusMap; import org.freedesktop.dbus.DBusPath; @@ -547,14 +548,32 @@ public class DbusManagerImpl implements Manager { } @Override - public List> getContacts() { - return signal.listNumbers().stream().map(n -> { + public List getRecipients( + final boolean onlyContacts, + final Optional blocked, + final Collection addresses, + final Optional name + ) { + final var numbers = addresses.stream() + .filter(s -> s instanceof RecipientIdentifier.Number) + .map(s -> ((RecipientIdentifier.Number) s).number()) + .collect(Collectors.toSet()); + return signal.listNumbers().stream().filter(n -> addresses.isEmpty() || numbers.contains(n)).map(n -> { + final var contactBlocked = signal.isContactBlocked(n); + if (blocked.isPresent() && blocked.get() != contactBlocked) { + return null; + } final var contactName = signal.getContactName(n); - if (contactName.length() == 0) { + if (onlyContacts && contactName.length() == 0) { + return null; + } + if (name.isPresent() && !name.get().equals(contactName)) { return null; } - return new Pair<>(new RecipientAddress(null, n), - new Contact(contactName, null, 0, signal.isContactBlocked(n), false, false)); + return Recipient.newBuilder() + .withAddress(new RecipientAddress(null, n)) + .withContact(new Contact(contactName, null, 0, contactBlocked, false, false)) + .build(); }).filter(Objects::nonNull).toList(); } diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index b4485e32..f4a9cda8 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -4,14 +4,12 @@ import org.asamk.Signal; import org.asamk.signal.BaseConfig; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.api.AttachmentInvalidException; -import org.asamk.signal.manager.api.Identity; import org.asamk.signal.manager.api.InactiveGroupLinkException; import org.asamk.signal.manager.api.InvalidDeviceLinkException; import org.asamk.signal.manager.api.InvalidNumberException; import org.asamk.signal.manager.api.InvalidStickerException; import org.asamk.signal.manager.api.Message; import org.asamk.signal.manager.api.NotMasterDeviceException; -import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.SendMessageResult; import org.asamk.signal.manager.api.SendMessageResults; @@ -28,7 +26,6 @@ import org.asamk.signal.manager.groups.GroupPermission; import org.asamk.signal.manager.groups.GroupSendingNotAllowedException; import org.asamk.signal.manager.groups.LastGroupAdminException; import org.asamk.signal.manager.groups.NotAGroupMemberException; -import org.asamk.signal.manager.storage.recipients.Profile; import org.asamk.signal.manager.storage.recipients.RecipientAddress; import org.asamk.signal.util.SendMessageResultUtils; import org.freedesktop.dbus.DBusPath; @@ -55,7 +52,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; public class DbusSignalImpl implements Signal { @@ -719,9 +715,9 @@ public class DbusSignalImpl implements Signal { // all numbers the system knows @Override public List listNumbers() { - return Stream.concat(m.getIdentities().stream().map(Identity::recipient), - m.getContacts().stream().map(Pair::first)) - .map(a -> a.number().orElse(null)) + return m.getRecipients(false, Optional.empty(), Set.of(), Optional.empty()) + .stream() + .map(r -> r.getAddress().number().orElse(null)) .filter(Objects::nonNull) .distinct() .toList(); @@ -729,30 +725,10 @@ public class DbusSignalImpl implements Signal { @Override public List getContactNumber(final String name) { - // Contact names have precedence. - var numbers = new ArrayList(); - var contacts = m.getContacts(); - for (var c : contacts) { - if (name.equals(c.second().getName())) { - numbers.add(c.first().getLegacyIdentifier()); - } - } - // Try profiles if no contact name was found - for (var identity : m.getIdentities()) { - final var address = identity.recipient(); - var number = address.number().orElse(null); - if (number != null) { - Profile profile = null; - try { - profile = m.getRecipientProfile(RecipientIdentifier.Single.fromAddress(address)); - } catch (IOException | UnregisteredRecipientException ignored) { - } - if (profile != null && profile.getDisplayName().equals(name)) { - numbers.add(number); - } - } - } - return numbers; + return m.getRecipients(false, Optional.empty(), Set.of(), Optional.of(name)) + .stream() + .map(r -> r.getAddress().getLegacyIdentifier()) + .toList(); } @Override -- 2.50.1