package org.asamk.signal.manager;
+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.InvalidStickerException;
import org.asamk.signal.manager.api.Message;
import org.asamk.signal.manager.api.MessageEnvelope;
+import org.asamk.signal.manager.api.NotPrimaryDeviceException;
import org.asamk.signal.manager.api.Pair;
+import org.asamk.signal.manager.api.ReceiveConfig;
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;
+import org.asamk.signal.manager.api.UpdateProfile;
+import org.asamk.signal.manager.api.UserStatus;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
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.SignalAccount;
-import org.asamk.signal.manager.storage.identities.TrustNewIdentity;
-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;
import java.io.IOException;
import java.net.URI;
import java.time.Duration;
-import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.UUID;
public interface Manager extends Closeable {
- static Manager init(
- String number,
- File settingsPath,
- ServiceEnvironment serviceEnvironment,
- String userAgent,
- TrustNewIdentity trustNewIdentity
- ) throws IOException, NotRegisteredException {
- var pathConfig = PathConfig.createDefault(settingsPath);
-
- if (!SignalAccount.userExists(pathConfig.dataPath(), number)) {
- throw new NotRegisteredException();
- }
-
- 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);
- }
-
- static void initLogger() {
- LibSignalLogger.initLogger();
- }
-
static boolean isValidNumber(final String e164Number, final String countryCode) {
return PhoneNumberFormatter.isValidNumber(e164Number, countryCode);
}
- static List<String> getAllLocalAccountNumbers(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))
- .toList();
- }
-
String getSelfNumber();
- void checkAccountState() throws IOException;
-
/**
* This is used for checking a set of phone numbers for registration on Signal
*
* @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;
+ Map<String, UserStatus> getUserStatus(Set<String> numbers) throws IOException;
void updateAccountAttributes(String deviceName) throws IOException;
Configuration getConfiguration();
- void updateConfiguration(Configuration configuration) throws IOException, NotMasterDeviceException;
+ void updateConfiguration(Configuration configuration) throws IOException, NotPrimaryDeviceException;
/**
- * @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),
+ * Update the user's profile.
+ * If a field is null, the previous value will be kept.
*/
- void setProfile(
- String givenName, String familyName, String about, String aboutEmoji, Optional<File> avatar
- ) throws IOException;
+ void updateProfile(UpdateProfile updateProfile) throws IOException;
void unregister() throws IOException;
void addDeviceLink(URI linkUri) throws IOException, InvalidDeviceLinkException;
- void setRegistrationLockPin(Optional<String> pin) throws IOException, NotMasterDeviceException;
+ void setRegistrationLockPin(Optional<String> pin) throws IOException, NotPrimaryDeviceException;
Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException;
Set<RecipientIdentifier> recipients
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException;
+ SendMessageResults sendPaymentNotificationMessage(
+ byte[] receipt, String note, RecipientIdentifier.Single recipient
+ ) throws IOException;
+
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, UnregisteredRecipientException;
+ RecipientIdentifier.Single recipient, String givenName, final String familyName
+ ) throws NotPrimaryDeviceException, IOException, UnregisteredRecipientException;
- void setContactBlocked(
- RecipientIdentifier.Single recipient, boolean blocked
- ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException;
+ void setContactsBlocked(
+ Collection<RecipientIdentifier.Single> recipient, boolean blocked
+ ) throws NotPrimaryDeviceException, IOException, UnregisteredRecipientException;
- void setGroupBlocked(
- GroupId groupId, boolean blocked
- ) throws GroupNotFoundException, IOException, NotMasterDeviceException;
+ void setGroupsBlocked(
+ Collection<GroupId> groupId, boolean blocked
+ ) throws GroupNotFoundException, IOException, NotPrimaryDeviceException;
/**
* Change the expiration timer for a contact
*/
void receiveMessages(ReceiveMessageHandler handler) throws IOException;
- void setIgnoreAttachments(boolean ignoreAttachments);
+ void setReceiveConfig(ReceiveConfig receiveConfig);
boolean hasCaughtUpWithOldMessages();
void sendContacts() throws IOException;
- List<Pair<RecipientAddress, Contact>> getContacts();
+ List<Recipient> getRecipients(
+ boolean onlyContacts,
+ Optional<Boolean> blocked,
+ Collection<RecipientIdentifier.Single> address,
+ Optional<String> name
+ );
String getContactOrProfileName(RecipientIdentifier.Single recipient);
*/
boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException;
+ void addAddressChangedListener(Runnable listener);
+
void addClosedListener(Runnable listener);
@Override