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
.util
.ErrorUtils
;
10 import org
.freedesktop
.dbus
.exceptions
.DBusExecutionException
;
11 import org
.whispersystems
.libsignal
.util
.guava
.Optional
;
12 import org
.whispersystems
.signalservice
.api
.messages
.SendMessageResult
;
13 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
14 import org
.whispersystems
.signalservice
.api
.util
.InvalidNumberException
;
17 import java
.io
.IOException
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
20 import java
.util
.stream
.Collectors
;
22 public class DbusSignalImpl
implements Signal
{
24 private final Manager m
;
26 public DbusSignalImpl(final Manager m
) {
31 public boolean isRemote() {
36 public String
getObjectPath() {
41 public long sendMessage(final String message
, final List
<String
> attachments
, final String recipient
) {
42 var recipients
= new ArrayList
<String
>(1);
43 recipients
.add(recipient
);
44 return sendMessage(message
, attachments
, recipients
);
47 private static void checkSendMessageResult(long timestamp
, SendMessageResult result
) throws DBusExecutionException
{
48 var error
= ErrorUtils
.getErrorMessageFromSendMessageResult(result
);
54 final var message
= timestamp
+ "\nFailed to send message:\n" + error
+ '\n';
56 if (result
.getIdentityFailure() != null) {
57 throw new Error
.UntrustedIdentity(message
);
59 throw new Error
.Failure(message
);
63 private static void checkSendMessageResults(
64 long timestamp
, List
<SendMessageResult
> results
65 ) throws DBusExecutionException
{
66 if (results
.size() == 1) {
67 checkSendMessageResult(timestamp
, results
.get(0));
71 var errors
= ErrorUtils
.getErrorMessagesFromSendMessageResults(results
);
72 if (errors
.size() == 0) {
76 var message
= new StringBuilder();
77 message
.append(timestamp
).append('\n');
78 message
.append("Failed to send (some) messages:\n");
79 for (var error
: errors
) {
80 message
.append(error
).append('\n');
83 throw new Error
.Failure(message
.toString());
87 public long sendMessage(final String message
, final List
<String
> attachments
, final List
<String
> recipients
) {
89 final var results
= m
.sendMessage(message
, attachments
, recipients
);
90 checkSendMessageResults(results
.first(), results
.second());
91 return results
.first();
92 } catch (InvalidNumberException e
) {
93 throw new Error
.InvalidNumber(e
.getMessage());
94 } catch (AttachmentInvalidException e
) {
95 throw new Error
.AttachmentInvalid(e
.getMessage());
96 } catch (IOException e
) {
97 throw new Error
.Failure(e
.getMessage());
102 public long sendNoteToSelfMessage(
103 final String message
, final List
<String
> attachments
104 ) throws Error
.AttachmentInvalid
, Error
.Failure
, Error
.UntrustedIdentity
{
106 final var results
= m
.sendSelfMessage(message
, attachments
);
107 checkSendMessageResult(results
.first(), results
.second());
108 return results
.first();
109 } catch (AttachmentInvalidException e
) {
110 throw new Error
.AttachmentInvalid(e
.getMessage());
111 } catch (IOException e
) {
112 throw new Error
.Failure(e
.getMessage());
117 public void sendEndSessionMessage(final List
<String
> recipients
) {
119 final var results
= m
.sendEndSessionMessage(recipients
);
120 checkSendMessageResults(results
.first(), results
.second());
121 } catch (IOException e
) {
122 throw new Error
.Failure(e
.getMessage());
123 } catch (InvalidNumberException e
) {
124 throw new Error
.InvalidNumber(e
.getMessage());
129 public long sendGroupMessage(final String message
, final List
<String
> attachments
, final byte[] groupId
) {
131 var results
= m
.sendGroupMessage(message
, attachments
, GroupId
.unknownVersion(groupId
));
132 checkSendMessageResults(results
.first(), results
.second());
133 return results
.first();
134 } catch (IOException e
) {
135 throw new Error
.Failure(e
.getMessage());
136 } catch (GroupNotFoundException
| NotAGroupMemberException e
) {
137 throw new Error
.GroupNotFound(e
.getMessage());
138 } catch (AttachmentInvalidException e
) {
139 throw new Error
.AttachmentInvalid(e
.getMessage());
144 public String
getContactName(final String number
) {
146 return m
.getContactName(number
);
147 } catch (InvalidNumberException e
) {
148 throw new Error
.InvalidNumber(e
.getMessage());
153 public void setContactName(final String number
, final String name
) {
155 m
.setContactName(number
, name
);
156 } catch (InvalidNumberException e
) {
157 throw new Error
.InvalidNumber(e
.getMessage());
162 public void setContactBlocked(final String number
, final boolean blocked
) {
164 m
.setContactBlocked(number
, blocked
);
165 } catch (InvalidNumberException e
) {
166 throw new Error
.InvalidNumber(e
.getMessage());
171 public void setGroupBlocked(final byte[] groupId
, final boolean blocked
) {
173 m
.setGroupBlocked(GroupId
.unknownVersion(groupId
), blocked
);
174 } catch (GroupNotFoundException e
) {
175 throw new Error
.GroupNotFound(e
.getMessage());
180 public List
<byte[]> getGroupIds() {
181 var groups
= m
.getGroups();
182 var ids
= new ArrayList
<byte[]>(groups
.size());
183 for (var group
: groups
) {
184 ids
.add(group
.getGroupId().serialize());
190 public String
getGroupName(final byte[] groupId
) {
191 var group
= m
.getGroup(GroupId
.unknownVersion(groupId
));
195 return group
.getTitle();
200 public List
<String
> getGroupMembers(final byte[] groupId
) {
201 var group
= m
.getGroup(GroupId
.unknownVersion(groupId
));
205 return group
.getMembers()
207 .map(m
::resolveSignalServiceAddress
)
208 .map(SignalServiceAddress
::getLegacyIdentifier
)
209 .collect(Collectors
.toList());
214 public byte[] updateGroup(byte[] groupId
, String name
, List
<String
> members
, String avatar
) {
216 if (groupId
.length
== 0) {
219 if (name
.isEmpty()) {
222 if (members
.isEmpty()) {
225 if (avatar
.isEmpty()) {
228 final var results
= m
.updateGroup(groupId
== null ?
null : GroupId
.unknownVersion(groupId
),
231 avatar
== null ?
null : new File(avatar
));
232 checkSendMessageResults(0, results
.second());
233 return results
.first().serialize();
234 } catch (IOException e
) {
235 throw new Error
.Failure(e
.getMessage());
236 } catch (GroupNotFoundException
| NotAGroupMemberException e
) {
237 throw new Error
.GroupNotFound(e
.getMessage());
238 } catch (InvalidNumberException e
) {
239 throw new Error
.InvalidNumber(e
.getMessage());
240 } catch (AttachmentInvalidException e
) {
241 throw new Error
.AttachmentInvalid(e
.getMessage());
246 public boolean isRegistered() {
251 public void updateProfile(
254 final String aboutEmoji
,
256 final boolean removeAvatar
259 if (avatarPath
.isEmpty()) {
262 Optional
<File
> avatarFile
= removeAvatar
264 : avatarPath
== null ?
null : Optional
.of(new File(avatarPath
));
265 m
.setProfile(name
, about
, aboutEmoji
, avatarFile
);
266 } catch (IOException e
) {
267 throw new Error
.Failure(e
.getMessage());