]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/Manager.java
Removing linked devices only works on the primary device
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / Manager.java
1 package org.asamk.signal.manager;
2
3 import org.asamk.signal.manager.api.AlreadyReceivingException;
4 import org.asamk.signal.manager.api.AttachmentInvalidException;
5 import org.asamk.signal.manager.api.CaptchaRequiredException;
6 import org.asamk.signal.manager.api.Configuration;
7 import org.asamk.signal.manager.api.Device;
8 import org.asamk.signal.manager.api.DeviceLinkUrl;
9 import org.asamk.signal.manager.api.Group;
10 import org.asamk.signal.manager.api.GroupId;
11 import org.asamk.signal.manager.api.GroupInviteLinkUrl;
12 import org.asamk.signal.manager.api.GroupNotFoundException;
13 import org.asamk.signal.manager.api.GroupSendingNotAllowedException;
14 import org.asamk.signal.manager.api.Identity;
15 import org.asamk.signal.manager.api.IdentityVerificationCode;
16 import org.asamk.signal.manager.api.InactiveGroupLinkException;
17 import org.asamk.signal.manager.api.IncorrectPinException;
18 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
19 import org.asamk.signal.manager.api.InvalidStickerException;
20 import org.asamk.signal.manager.api.InvalidUsernameException;
21 import org.asamk.signal.manager.api.LastGroupAdminException;
22 import org.asamk.signal.manager.api.Message;
23 import org.asamk.signal.manager.api.MessageEnvelope;
24 import org.asamk.signal.manager.api.NonNormalizedPhoneNumberException;
25 import org.asamk.signal.manager.api.NotAGroupMemberException;
26 import org.asamk.signal.manager.api.NotPrimaryDeviceException;
27 import org.asamk.signal.manager.api.Pair;
28 import org.asamk.signal.manager.api.PendingAdminApprovalException;
29 import org.asamk.signal.manager.api.PinLockedException;
30 import org.asamk.signal.manager.api.RateLimitException;
31 import org.asamk.signal.manager.api.ReceiveConfig;
32 import org.asamk.signal.manager.api.Recipient;
33 import org.asamk.signal.manager.api.RecipientIdentifier;
34 import org.asamk.signal.manager.api.SendGroupMessageResults;
35 import org.asamk.signal.manager.api.SendMessageResults;
36 import org.asamk.signal.manager.api.StickerPack;
37 import org.asamk.signal.manager.api.StickerPackId;
38 import org.asamk.signal.manager.api.StickerPackInvalidException;
39 import org.asamk.signal.manager.api.StickerPackUrl;
40 import org.asamk.signal.manager.api.TypingAction;
41 import org.asamk.signal.manager.api.UnregisteredRecipientException;
42 import org.asamk.signal.manager.api.UpdateGroup;
43 import org.asamk.signal.manager.api.UpdateProfile;
44 import org.asamk.signal.manager.api.UserStatus;
45 import org.asamk.signal.manager.api.UsernameLinkUrl;
46 import org.asamk.signal.manager.api.VerificationMethoNotAvailableException;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49 import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
50
51 import java.io.Closeable;
52 import java.io.File;
53 import java.io.IOException;
54 import java.io.InputStream;
55 import java.time.Duration;
56 import java.util.Collection;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.Optional;
60 import java.util.Set;
61
62 public interface Manager extends Closeable {
63
64 static boolean isValidNumber(final String e164Number, final String countryCode) {
65 return PhoneNumberFormatter.isValidNumber(e164Number, countryCode);
66 }
67
68 static boolean isSignalClientAvailable() {
69 final Logger logger = LoggerFactory.getLogger(Manager.class);
70 try {
71 try {
72 org.signal.libsignal.internal.Native.UuidCiphertext_CheckValidContents(new byte[0]);
73 } catch (Exception e) {
74 logger.trace("Expected exception when checking libsignal-client: {}", e.getMessage());
75 }
76 return true;
77 } catch (UnsatisfiedLinkError e) {
78 logger.warn("Failed to call libsignal-client: {}", e.getMessage());
79 return false;
80 }
81 }
82
83 String getSelfNumber();
84
85 /**
86 * This is used for checking a set of phone numbers for registration on Signal
87 *
88 * @param numbers The set of phone number in question
89 * @return A map of numbers to canonicalized number and uuid. If a number is not registered the uuid is null.
90 * @throws IOException if it's unable to get the contacts to check if they're registered
91 */
92 Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException, RateLimitException;
93
94 void updateAccountAttributes(
95 String deviceName,
96 Boolean unrestrictedUnidentifiedSender,
97 final Boolean discoverableByNumber,
98 final Boolean numberSharing
99 ) throws IOException;
100
101 Configuration getConfiguration();
102
103 void updateConfiguration(Configuration configuration) throws NotPrimaryDeviceException;
104
105 /**
106 * Update the user's profile.
107 * If a field is null, the previous value will be kept.
108 */
109 void updateProfile(UpdateProfile updateProfile) throws IOException;
110
111 String getUsername();
112
113 UsernameLinkUrl getUsernameLink();
114
115 /**
116 * Set a username for the account.
117 * If the username is null, it will be deleted.
118 */
119 void setUsername(String username) throws IOException, InvalidUsernameException;
120
121 /**
122 * Set a username for the account.
123 * If the username is null, it will be deleted.
124 */
125 void deleteUsername() throws IOException;
126
127 void startChangeNumber(
128 String newNumber, boolean voiceVerification, String captcha
129 ) throws RateLimitException, IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException, NotPrimaryDeviceException, VerificationMethoNotAvailableException;
130
131 void finishChangeNumber(
132 String newNumber, String verificationCode, String pin
133 ) throws IncorrectPinException, PinLockedException, IOException, NotPrimaryDeviceException;
134
135 void unregister() throws IOException;
136
137 void deleteAccount() throws IOException;
138
139 void submitRateLimitRecaptchaChallenge(String challenge, String captcha) throws IOException;
140
141 List<Device> getLinkedDevices() throws IOException;
142
143 void removeLinkedDevices(int deviceId) throws IOException, NotPrimaryDeviceException;
144
145 void addDeviceLink(DeviceLinkUrl linkUri) throws IOException, InvalidDeviceLinkException, NotPrimaryDeviceException;
146
147 void setRegistrationLockPin(Optional<String> pin) throws IOException, NotPrimaryDeviceException;
148
149 List<Group> getGroups();
150
151 SendGroupMessageResults quitGroup(
152 GroupId groupId, Set<RecipientIdentifier.Single> groupAdmins
153 ) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException, UnregisteredRecipientException;
154
155 void deleteGroup(GroupId groupId) throws IOException;
156
157 Pair<GroupId, SendGroupMessageResults> createGroup(
158 String name, Set<RecipientIdentifier.Single> members, String avatarFile
159 ) throws IOException, AttachmentInvalidException, UnregisteredRecipientException;
160
161 SendGroupMessageResults updateGroup(
162 final GroupId groupId, final UpdateGroup updateGroup
163 ) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException, UnregisteredRecipientException;
164
165 Pair<GroupId, SendGroupMessageResults> joinGroup(
166 GroupInviteLinkUrl inviteLinkUrl
167 ) throws IOException, InactiveGroupLinkException, PendingAdminApprovalException;
168
169 SendMessageResults sendTypingMessage(
170 TypingAction action, Set<RecipientIdentifier> recipients
171 ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
172
173 SendMessageResults sendReadReceipt(
174 RecipientIdentifier.Single sender, List<Long> messageIds
175 );
176
177 SendMessageResults sendViewedReceipt(
178 RecipientIdentifier.Single sender, List<Long> messageIds
179 );
180
181 SendMessageResults sendMessage(
182 Message message, Set<RecipientIdentifier> recipients, boolean notifySelf
183 ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException;
184
185 SendMessageResults sendEditMessage(
186 Message message, Set<RecipientIdentifier> recipients, long editTargetTimestamp
187 ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException;
188
189 SendMessageResults sendRemoteDeleteMessage(
190 long targetSentTimestamp, Set<RecipientIdentifier> recipients
191 ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
192
193 SendMessageResults sendMessageReaction(
194 String emoji,
195 boolean remove,
196 RecipientIdentifier.Single targetAuthor,
197 long targetSentTimestamp,
198 Set<RecipientIdentifier> recipients,
199 final boolean isStory
200 ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException;
201
202 SendMessageResults sendPaymentNotificationMessage(
203 byte[] receipt, String note, RecipientIdentifier.Single recipient
204 ) throws IOException;
205
206 SendMessageResults sendEndSessionMessage(Set<RecipientIdentifier.Single> recipients) throws IOException;
207
208 SendMessageResults sendMessageRequestResponse(
209 MessageEnvelope.Sync.MessageRequestResponse.Type type, Set<RecipientIdentifier> recipientIdentifiers
210 );
211
212 void hideRecipient(RecipientIdentifier.Single recipient);
213
214 void deleteRecipient(RecipientIdentifier.Single recipient);
215
216 void deleteContact(RecipientIdentifier.Single recipient);
217
218 void setContactName(
219 RecipientIdentifier.Single recipient, String givenName, final String familyName
220 ) throws NotPrimaryDeviceException, UnregisteredRecipientException;
221
222 void setContactsBlocked(
223 Collection<RecipientIdentifier.Single> recipient, boolean blocked
224 ) throws NotPrimaryDeviceException, IOException, UnregisteredRecipientException;
225
226 void setGroupsBlocked(
227 Collection<GroupId> groupId, boolean blocked
228 ) throws GroupNotFoundException, IOException, NotPrimaryDeviceException;
229
230 /**
231 * Change the expiration timer for a contact
232 */
233 void setExpirationTimer(
234 RecipientIdentifier.Single recipient, int messageExpirationTimer
235 ) throws IOException, UnregisteredRecipientException;
236
237 /**
238 * Upload the sticker pack from path.
239 *
240 * @param path Path can be a path to a manifest.json file or to a zip file that contains a manifest.json file
241 * @return if successful, returns the URL to install the sticker pack in the signal app
242 */
243 StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
244
245 void installStickerPack(StickerPackUrl url) throws IOException;
246
247 List<StickerPack> getStickerPacks();
248
249 void requestAllSyncData() throws IOException;
250
251 /**
252 * Add a handler to receive new messages.
253 * Will start receiving messages from server, if not already started.
254 */
255 default void addReceiveHandler(ReceiveMessageHandler handler) {
256 addReceiveHandler(handler, false);
257 }
258
259 void addReceiveHandler(ReceiveMessageHandler handler, final boolean isWeakListener);
260
261 /**
262 * Remove a handler to receive new messages.
263 * Will stop receiving messages from server, if this was the last registered receiver.
264 */
265 void removeReceiveHandler(ReceiveMessageHandler handler);
266
267 boolean isReceiving();
268
269 /**
270 * Receive new messages from server, returns if no new message arrive in a timespan of timeout.
271 */
272 void receiveMessages(
273 Optional<Duration> timeout, Optional<Integer> maxMessages, ReceiveMessageHandler handler
274 ) throws IOException, AlreadyReceivingException;
275
276 void stopReceiveMessages();
277
278 void setReceiveConfig(ReceiveConfig receiveConfig);
279
280 boolean isContactBlocked(RecipientIdentifier.Single recipient);
281
282 void sendContacts() throws IOException;
283
284 List<Recipient> getRecipients(
285 boolean onlyContacts,
286 Optional<Boolean> blocked,
287 Collection<RecipientIdentifier.Single> address,
288 Optional<String> name
289 );
290
291 String getContactOrProfileName(RecipientIdentifier.Single recipient);
292
293 Group getGroup(GroupId groupId);
294
295 List<Identity> getIdentities();
296
297 List<Identity> getIdentities(RecipientIdentifier.Single recipient);
298
299 /**
300 * Trust this the identity with this fingerprint/safetyNumber
301 *
302 * @param recipient account of the identity
303 */
304 boolean trustIdentityVerified(
305 RecipientIdentifier.Single recipient, IdentityVerificationCode verificationCode
306 ) throws UnregisteredRecipientException;
307
308 /**
309 * Trust all keys of this identity without verification
310 *
311 * @param recipient account of the identity
312 */
313 boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException;
314
315 void addAddressChangedListener(Runnable listener);
316
317 void addClosedListener(Runnable listener);
318
319 InputStream retrieveAttachment(final String id) throws IOException;
320
321 InputStream retrieveContactAvatar(final RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException;
322
323 InputStream retrieveProfileAvatar(final RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException;
324
325 InputStream retrieveGroupAvatar(final GroupId groupId) throws IOException;
326
327 InputStream retrieveSticker(final StickerPackId stickerPackId, final int stickerId) throws IOException;
328
329 @Override
330 void close();
331
332 interface ReceiveMessageHandler {
333
334 ReceiveMessageHandler EMPTY = (envelope, e) -> {
335 };
336
337 void handleMessage(MessageEnvelope envelope, Throwable e);
338 }
339 }