]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/Manager.java
Cleanup manager package
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / Manager.java
index b4579274b738c4372a8d0f9ace7213bbf08eb718..b7a97c469373c3ae4dab5d075f1dba416e35e439 100644 (file)
@@ -1,17 +1,27 @@
 package org.asamk.signal.manager;
 
+import org.asamk.signal.manager.api.AccountCheckException;
+import org.asamk.signal.manager.api.AttachmentInvalidException;
+import org.asamk.signal.manager.api.Configuration;
 import org.asamk.signal.manager.api.Device;
 import org.asamk.signal.manager.api.Group;
 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.InvalidStickerException;
 import org.asamk.signal.manager.api.Message;
 import org.asamk.signal.manager.api.MessageEnvelope;
+import org.asamk.signal.manager.api.NotMasterDeviceException;
+import org.asamk.signal.manager.api.NotRegisteredException;
 import org.asamk.signal.manager.api.Pair;
 import org.asamk.signal.manager.api.RecipientIdentifier;
 import org.asamk.signal.manager.api.SendGroupMessageResults;
 import org.asamk.signal.manager.api.SendMessageResults;
+import org.asamk.signal.manager.api.StickerPack;
+import org.asamk.signal.manager.api.StickerPackInvalidException;
+import org.asamk.signal.manager.api.StickerPackUrl;
 import org.asamk.signal.manager.api.TypingAction;
+import org.asamk.signal.manager.api.UnregisteredRecipientException;
 import org.asamk.signal.manager.api.UpdateGroup;
 import org.asamk.signal.manager.config.ServiceConfig;
 import org.asamk.signal.manager.config.ServiceEnvironment;
@@ -32,14 +42,12 @@ import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
-import java.util.Arrays;
+import java.time.Duration;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 public interface Manager extends Closeable {
 
@@ -49,7 +57,7 @@ public interface Manager extends Closeable {
             ServiceEnvironment serviceEnvironment,
             String userAgent,
             TrustNewIdentity trustNewIdentity
-    ) throws IOException, NotRegisteredException {
+    ) throws IOException, NotRegisteredException, AccountCheckException {
         var pathConfig = PathConfig.createDefault(settingsPath);
 
         if (!SignalAccount.userExists(pathConfig.dataPath(), number)) {
@@ -59,12 +67,23 @@ public interface Manager extends Closeable {
         var account = SignalAccount.load(pathConfig.dataPath(), number, true, trustNewIdentity);
 
         if (!account.isRegistered()) {
+            account.close();
             throw new NotRegisteredException();
         }
 
+        account.initDatabase();
         final var serviceEnvironmentConfig = ServiceConfig.getServiceEnvironmentConfig(serviceEnvironment, userAgent);
 
-        return new ManagerImpl(account, pathConfig, serviceEnvironmentConfig, userAgent);
+        final var manager = new ManagerImpl(account, pathConfig, serviceEnvironmentConfig, userAgent);
+
+        try {
+            manager.checkAccountState();
+        } catch (IOException e) {
+            manager.close();
+            throw new AccountCheckException("Error while checking account " + account + ": " + e.getMessage(), e);
+        }
+
+        return manager;
     }
 
     static void initLogger() {
@@ -75,37 +94,30 @@ public interface Manager extends Closeable {
         return PhoneNumberFormatter.isValidNumber(e164Number, countryCode);
     }
 
-    static List<String> getAllLocalNumbers(File settingsPath) {
-        var pathConfig = PathConfig.createDefault(settingsPath);
-        final var dataPath = pathConfig.dataPath();
-        final var files = dataPath.listFiles();
-
-        if (files == null) {
-            return List.of();
-        }
-
-        return Arrays.stream(files)
-                .filter(File::isFile)
-                .map(File::getName)
-                .filter(file -> PhoneNumberFormatter.isValidNumber(file, null))
-                .collect(Collectors.toList());
-    }
-
     String getSelfNumber();
 
-    void checkAccountState() throws IOException;
-
+    /**
+     * This is used for checking a set of phone numbers for registration on Signal
+     *
+     * @param numbers The set of phone number in question
+     * @return A map of numbers to canonicalized number and uuid. If a number is not registered the uuid is null.
+     * @throws IOException if it's unable to get the contacts to check if they're registered
+     */
     Map<String, Pair<String, UUID>> areUsersRegistered(Set<String> numbers) throws IOException;
 
     void updateAccountAttributes(String deviceName) throws IOException;
 
-    void updateConfiguration(
-            final Boolean readReceipts,
-            final Boolean unidentifiedDeliveryIndicators,
-            final Boolean typingIndicators,
-            final Boolean linkPreviews
-    ) throws IOException, NotMasterDeviceException;
+    Configuration getConfiguration();
+
+    void updateConfiguration(Configuration configuration) throws IOException, NotMasterDeviceException;
 
+    /**
+     * @param givenName  if null, the previous givenName will be kept
+     * @param familyName if null, the previous familyName will be kept
+     * @param about      if null, the previous about text will be kept
+     * @param aboutEmoji if null, the previous about emoji will be kept
+     * @param avatar     if avatar is null the image from the local avatar store is used (if present),
+     */
     void setProfile(
             String givenName, String familyName, String about, String aboutEmoji, Optional<File> avatar
     ) throws IOException;
@@ -118,49 +130,49 @@ public interface Manager extends Closeable {
 
     List<Device> getLinkedDevices() throws IOException;
 
-    void removeLinkedDevices(long deviceId) throws IOException;
+    void removeLinkedDevices(int deviceId) throws IOException;
 
     void addDeviceLink(URI linkUri) throws IOException, InvalidDeviceLinkException;
 
-    void setRegistrationLockPin(Optional<String> pin) throws IOException;
+    void setRegistrationLockPin(Optional<String> pin) throws IOException, NotMasterDeviceException;
 
-    Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException;
+    Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException;
 
     List<Group> getGroups();
 
     SendGroupMessageResults quitGroup(
             GroupId groupId, Set<RecipientIdentifier.Single> groupAdmins
-    ) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException;
+    ) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException, UnregisteredRecipientException;
 
     void deleteGroup(GroupId groupId) throws IOException;
 
     Pair<GroupId, SendGroupMessageResults> createGroup(
             String name, Set<RecipientIdentifier.Single> members, File avatarFile
-    ) throws IOException, AttachmentInvalidException;
+    ) throws IOException, AttachmentInvalidException, UnregisteredRecipientException;
 
     SendGroupMessageResults updateGroup(
             final GroupId groupId, final UpdateGroup updateGroup
-    ) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException;
+    ) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException, UnregisteredRecipientException;
 
     Pair<GroupId, SendGroupMessageResults> joinGroup(
             GroupInviteLinkUrl inviteLinkUrl
     ) throws IOException, InactiveGroupLinkException;
 
-    void sendTypingMessage(
+    SendMessageResults sendTypingMessage(
             TypingAction action, Set<RecipientIdentifier> recipients
-    ) throws IOException, UntrustedIdentityException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
+    ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
 
-    void sendReadReceipt(
+    SendMessageResults sendReadReceipt(
             RecipientIdentifier.Single sender, List<Long> messageIds
-    ) throws IOException, UntrustedIdentityException;
+    ) throws IOException;
 
-    void sendViewedReceipt(
+    SendMessageResults sendViewedReceipt(
             RecipientIdentifier.Single sender, List<Long> messageIds
-    ) throws IOException, UntrustedIdentityException;
+    ) throws IOException;
 
     SendMessageResults sendMessage(
             Message message, Set<RecipientIdentifier> recipients
-    ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
+    ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException;
 
     SendMessageResults sendRemoteDeleteMessage(
             long targetSentTimestamp, Set<RecipientIdentifier> recipients
@@ -172,27 +184,42 @@ public interface Manager extends Closeable {
             RecipientIdentifier.Single targetAuthor,
             long targetSentTimestamp,
             Set<RecipientIdentifier> recipients
-    ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException;
+    ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException;
 
     SendMessageResults sendEndSessionMessage(Set<RecipientIdentifier.Single> recipients) throws IOException;
 
+    void deleteRecipient(RecipientIdentifier.Single recipient);
+
+    void deleteContact(RecipientIdentifier.Single recipient);
+
     void setContactName(
             RecipientIdentifier.Single recipient, String name
-    ) throws NotMasterDeviceException, IOException;
+    ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException;
 
     void setContactBlocked(
             RecipientIdentifier.Single recipient, boolean blocked
-    ) throws NotMasterDeviceException, IOException;
+    ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException;
 
     void setGroupBlocked(
             GroupId groupId, boolean blocked
     ) throws GroupNotFoundException, IOException, NotMasterDeviceException;
 
+    /**
+     * Change the expiration timer for a contact
+     */
     void setExpirationTimer(
             RecipientIdentifier.Single recipient, int messageExpirationTimer
-    ) throws IOException;
+    ) throws IOException, UnregisteredRecipientException;
+
+    /**
+     * Upload the sticker pack from path.
+     *
+     * @param path Path can be a path to a manifest.json file or to a zip file that contains a manifest.json file
+     * @return if successful, returns the URL to install the sticker pack in the signal app
+     */
+    StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
 
-    URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
+    List<StickerPack> getStickerPacks();
 
     void requestAllSyncData() throws IOException;
 
@@ -200,7 +227,11 @@ public interface Manager extends Closeable {
      * Add a handler to receive new messages.
      * Will start receiving messages from server, if not already started.
      */
-    void addReceiveHandler(ReceiveMessageHandler handler);
+    default void addReceiveHandler(ReceiveMessageHandler handler) {
+        addReceiveHandler(handler, false);
+    }
+
+    void addReceiveHandler(ReceiveMessageHandler handler, final boolean isWeakListener);
 
     /**
      * Remove a handler to receive new messages.
@@ -213,7 +244,7 @@ public interface Manager extends Closeable {
     /**
      * Receive new messages from server, returns if no new message arrive in a timespan of timeout.
      */
-    void receiveMessages(long timeout, TimeUnit unit, ReceiveMessageHandler handler) throws IOException;
+    void receiveMessages(Duration timeout, ReceiveMessageHandler handler) throws IOException;
 
     /**
      * Receive new messages from server, returns only if the thread is interrupted.
@@ -226,8 +257,6 @@ public interface Manager extends Closeable {
 
     boolean isContactBlocked(RecipientIdentifier.Single recipient);
 
-    File getAttachmentFile(String attachmentId);
-
     void sendContacts() throws IOException;
 
     List<Pair<RecipientAddress, Contact>> getContacts();
@@ -240,19 +269,53 @@ public interface Manager extends Closeable {
 
     List<Identity> getIdentities(RecipientIdentifier.Single recipient);
 
-    boolean trustIdentityVerified(RecipientIdentifier.Single recipient, byte[] fingerprint);
+    /**
+     * Trust this the identity with this fingerprint
+     *
+     * @param recipient   account of the identity
+     * @param fingerprint Fingerprint
+     */
+    boolean trustIdentityVerified(
+            RecipientIdentifier.Single recipient, byte[] fingerprint
+    ) throws UnregisteredRecipientException;
+
+    /**
+     * Trust this the identity with this safety number
+     *
+     * @param recipient    account of the identity
+     * @param safetyNumber Safety number
+     */
+    boolean trustIdentityVerifiedSafetyNumber(
+            RecipientIdentifier.Single recipient, String safetyNumber
+    ) throws UnregisteredRecipientException;
 
-    boolean trustIdentityVerifiedSafetyNumber(RecipientIdentifier.Single recipient, String safetyNumber);
+    /**
+     * Trust this the identity with this scannable safety number
+     *
+     * @param recipient    account of the identity
+     * @param safetyNumber Scannable safety number
+     */
+    boolean trustIdentityVerifiedSafetyNumber(
+            RecipientIdentifier.Single recipient, byte[] safetyNumber
+    ) throws UnregisteredRecipientException;
 
-    boolean trustIdentityVerifiedSafetyNumber(RecipientIdentifier.Single recipient, byte[] safetyNumber);
+    /**
+     * Trust all keys of this identity without verification
+     *
+     * @param recipient account of the identity
+     */
+    boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException;
 
-    boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient);
+    void addClosedListener(Runnable listener);
 
     @Override
     void close() throws IOException;
 
     interface ReceiveMessageHandler {
 
+        ReceiveMessageHandler EMPTY = (envelope, e) -> {
+        };
+
         void handleMessage(MessageEnvelope envelope, Throwable e);
     }
 }