1 package org
.asamk
.signal
.dbus
;
3 import org
.asamk
.Signal
;
4 import org
.asamk
.signal
.manager
.AttachmentInvalidException
;
5 import org
.asamk
.signal
.manager
.Manager
;
6 import org
.asamk
.signal
.manager
.groups
.GroupId
;
7 import org
.asamk
.signal
.manager
.groups
.GroupNotFoundException
;
8 import org
.asamk
.signal
.manager
.groups
.NotAGroupMemberException
;
9 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfo
;
10 import org
.asamk
.signal
.util
.ErrorUtils
;
11 import org
.freedesktop
.dbus
.exceptions
.DBusExecutionException
;
12 import org
.whispersystems
.libsignal
.util
.Pair
;
13 import org
.whispersystems
.signalservice
.api
.messages
.SendMessageResult
;
14 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
15 import org
.whispersystems
.signalservice
.api
.util
.InvalidNumberException
;
16 import org
.whispersystems
.libsignal
.util
.guava
.Optional
;
17 import org
.asamk
.signal
.manager
.storage
.contacts
.ContactInfo
;
20 import java
.io
.IOException
;
21 import java
.util
.ArrayList
;
22 import java
.util
.List
;
23 import java
.util
.stream
.Collectors
;
25 public class DbusSignalImpl
implements Signal
{
27 private final Manager m
;
29 public DbusSignalImpl(final Manager m
) {
34 public boolean isRemote() {
39 public String
getObjectPath() {
44 public long sendMessage(final String message
, final List
<String
> attachments
, final String recipient
) {
45 List
<String
> recipients
= new ArrayList
<>(1);
46 recipients
.add(recipient
);
47 return sendMessage(message
, attachments
, recipients
);
50 private static void checkSendMessageResult(long timestamp
, SendMessageResult result
) throws DBusExecutionException
{
51 String error
= ErrorUtils
.getErrorMessageFromSendMessageResult(result
);
57 final String message
= timestamp
+ "\nFailed to send message:\n" + error
+ '\n';
59 if (result
.getIdentityFailure() != null) {
60 throw new Error
.UntrustedIdentity(message
);
62 throw new Error
.Failure(message
);
66 private static void checkSendMessageResults(
67 long timestamp
, List
<SendMessageResult
> results
68 ) throws DBusExecutionException
{
69 if (results
.size() == 1) {
70 checkSendMessageResult(timestamp
, results
.get(0));
74 List
<String
> errors
= ErrorUtils
.getErrorMessagesFromSendMessageResults(results
);
75 if (errors
.size() == 0) {
79 StringBuilder message
= new StringBuilder();
80 message
.append(timestamp
).append('\n');
81 message
.append("Failed to send (some) messages:\n");
82 for (String error
: errors
) {
83 message
.append(error
).append('\n');
86 throw new Error
.Failure(message
.toString());
90 public long sendMessage(final String message
, final List
<String
> attachments
, final List
<String
> recipients
) {
92 final Pair
<Long
, List
<SendMessageResult
>> results
= m
.sendMessage(message
, attachments
, recipients
);
93 checkSendMessageResults(results
.first(), results
.second());
94 return results
.first();
95 } catch (InvalidNumberException e
) {
96 throw new Error
.InvalidNumber(e
.getMessage());
97 } catch (AttachmentInvalidException e
) {
98 throw new Error
.AttachmentInvalid(e
.getMessage());
99 } catch (IOException e
) {
100 throw new Error
.Failure(e
.getMessage());
105 public long sendNoteToSelfMessage(
106 final String message
, final List
<String
> attachments
107 ) throws Error
.AttachmentInvalid
, Error
.Failure
, Error
.UntrustedIdentity
{
109 final Pair
<Long
, SendMessageResult
> results
= m
.sendSelfMessage(message
, attachments
);
110 checkSendMessageResult(results
.first(), results
.second());
111 return results
.first();
112 } catch (AttachmentInvalidException e
) {
113 throw new Error
.AttachmentInvalid(e
.getMessage());
114 } catch (IOException e
) {
115 throw new Error
.Failure(e
.getMessage());
120 public void sendEndSessionMessage(final List
<String
> recipients
) {
122 final Pair
<Long
, List
<SendMessageResult
>> results
= m
.sendEndSessionMessage(recipients
);
123 checkSendMessageResults(results
.first(), results
.second());
124 } catch (IOException e
) {
125 throw new Error
.Failure(e
.getMessage());
126 } catch (InvalidNumberException e
) {
127 throw new Error
.InvalidNumber(e
.getMessage());
132 public long sendGroupMessage(final String message
, final List
<String
> attachments
, final byte[] groupId
) {
134 Pair
<Long
, List
<SendMessageResult
>> results
= m
.sendGroupMessage(message
,
136 GroupId
.unknownVersion(groupId
));
137 checkSendMessageResults(results
.first(), results
.second());
138 return results
.first();
139 } catch (IOException e
) {
140 throw new Error
.Failure(e
.getMessage());
141 } catch (GroupNotFoundException
| NotAGroupMemberException e
) {
142 throw new Error
.GroupNotFound(e
.getMessage());
143 } catch (AttachmentInvalidException e
) {
144 throw new Error
.AttachmentInvalid(e
.getMessage());
149 public String
getContactName(final String number
) {
151 return m
.getContactName(number
);
152 } catch (InvalidNumberException e
) {
153 throw new Error
.InvalidNumber(e
.getMessage());
158 public void setContactName(final String number
, final String name
) {
160 m
.setContactName(number
, name
);
161 } catch (InvalidNumberException e
) {
162 throw new Error
.InvalidNumber(e
.getMessage());
167 public void setContactBlocked(final String number
, final boolean blocked
) {
169 m
.setContactBlocked(number
, blocked
);
170 } catch (InvalidNumberException e
) {
171 throw new Error
.InvalidNumber(e
.getMessage());
176 public void setGroupBlocked(final byte[] groupId
, final boolean blocked
) {
178 m
.setGroupBlocked(GroupId
.unknownVersion(groupId
), blocked
);
179 } catch (GroupNotFoundException e
) {
180 throw new Error
.GroupNotFound(e
.getMessage());
185 public List
<byte[]> getGroupIds() {
186 List
<GroupInfo
> groups
= m
.getGroups();
187 List
<byte[]> ids
= new ArrayList
<>(groups
.size());
188 for (GroupInfo group
: groups
) {
189 ids
.add(group
.getGroupId().serialize());
195 public String
getGroupName(final byte[] groupId
) {
196 GroupInfo group
= m
.getGroup(GroupId
.unknownVersion(groupId
));
200 return group
.getTitle();
205 public List
<String
> getGroupMembers(final byte[] groupId
) {
206 GroupInfo group
= m
.getGroup(GroupId
.unknownVersion(groupId
));
210 return group
.getMembers()
212 .map(m
::resolveSignalServiceAddress
)
213 .map(SignalServiceAddress
::getLegacyIdentifier
)
214 .collect(Collectors
.toList());
219 public byte[] updateGroup(byte[] groupId
, String name
, List
<String
> members
, String avatar
) {
221 if (groupId
.length
== 0) {
224 if (name
.isEmpty()) {
227 if (members
.isEmpty()) {
230 if (avatar
.isEmpty()) {
233 final Pair
<GroupId
, List
<SendMessageResult
>> results
= m
.updateGroup(groupId
== null
235 : GroupId
.unknownVersion(groupId
), name
, members
, avatar
== null ?
null : new File(avatar
));
236 checkSendMessageResults(0, results
.second());
237 return results
.first().serialize();
238 } catch (IOException e
) {
239 throw new Error
.Failure(e
.getMessage());
240 } catch (GroupNotFoundException
| NotAGroupMemberException e
) {
241 throw new Error
.GroupNotFound(e
.getMessage());
242 } catch (InvalidNumberException e
) {
243 throw new Error
.InvalidNumber(e
.getMessage());
244 } catch (AttachmentInvalidException e
) {
245 throw new Error
.AttachmentInvalid(e
.getMessage());
250 public boolean isRegistered() {
255 public void updateProfile(final String name
,final String about
,final String aboutEmoji
, String avatarPath
, final boolean removeAvatar
) {
257 if (avatarPath
.isEmpty()) {
260 Optional
<File
> avatarFile
= removeAvatar
262 : avatarPath
== null ?
null : Optional
.of(new File(avatarPath
));
263 m
.setProfile(name
, about
, aboutEmoji
, avatarFile
);
264 } catch (IOException e
) {
265 throw new Error
.Failure(e
.getMessage());