X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/7e223dc228b81edd2f9b42845d42ce26f1d88e13..a8bbdb54d006f157a009ece0cae5bf72fb636ced:/lib/src/main/java/org/asamk/signal/manager/Manager.java diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index 2500371f..98b02c7f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -34,6 +34,9 @@ import org.asamk.signal.manager.helper.GroupV2Helper; import org.asamk.signal.manager.helper.PinHelper; import org.asamk.signal.manager.helper.ProfileHelper; import org.asamk.signal.manager.helper.UnidentifiedAccessHelper; +import org.asamk.signal.manager.jobs.Context; +import org.asamk.signal.manager.jobs.Job; +import org.asamk.signal.manager.jobs.RetrieveStickerPackJob; import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.groups.GroupInfo; import org.asamk.signal.manager.storage.groups.GroupInfoV1; @@ -202,6 +205,7 @@ public class Manager implements Closeable { private final PinHelper pinHelper; private final AvatarStore avatarStore; private final AttachmentStore attachmentStore; + private final StickerPackStore stickerPackStore; private final SignalSessionLock sessionLock = new SignalSessionLock() { private final ReentrantLock LEGACY_LOCK = new ReentrantLock(); @@ -275,6 +279,7 @@ public class Manager implements Closeable { this::resolveSignalServiceAddress); this.avatarStore = new AvatarStore(pathConfig.getAvatarsPath()); this.attachmentStore = new AttachmentStore(pathConfig.getAttachmentsPath()); + this.stickerPackStore = new StickerPackStore(pathConfig.getStickerPacksPath()); } public String getUsername() { @@ -613,21 +618,27 @@ public class Manager implements Closeable { return null; } + profile = decryptProfileIfKeyKnown(recipientId, encryptedProfile); + account.getProfileStore().storeProfile(recipientId, profile); + + return profile; + } + + private Profile decryptProfileIfKeyKnown( + final RecipientId recipientId, final SignalServiceProfile encryptedProfile + ) { var profileKey = account.getProfileStore().getProfileKey(recipientId); if (profileKey == null) { - profile = new Profile(System.currentTimeMillis(), + return new Profile(System.currentTimeMillis(), null, null, null, null, ProfileUtils.getUnidentifiedAccessMode(encryptedProfile, null), ProfileUtils.getCapabilities(encryptedProfile)); - } else { - profile = decryptProfileAndDownloadAvatar(recipientId, profileKey, encryptedProfile); } - account.getProfileStore().storeProfile(recipientId, profile); - return profile; + return decryptProfileAndDownloadAvatar(recipientId, profileKey, encryptedProfile); } private SignalServiceProfile retrieveEncryptedProfile(RecipientId recipientId) { @@ -1434,18 +1445,20 @@ public class Manager implements Closeable { var messageSender = createMessageSender(); var packKey = KeyUtils.createStickerUploadKey(); - var packId = messageSender.uploadStickerManifest(manifest, packKey); + var packIdString = messageSender.uploadStickerManifest(manifest, packKey); + var packId = StickerPackId.deserialize(Hex.fromStringCondensed(packIdString)); - var sticker = new Sticker(StickerPackId.deserialize(Hex.fromStringCondensed(packId)), packKey); + var sticker = new Sticker(packId, packKey); account.getStickerStore().updateSticker(sticker); try { return new URI("https", "signal.art", "/addstickers/", - "pack_id=" + URLEncoder.encode(packId, StandardCharsets.UTF_8) + "&pack_key=" + URLEncoder.encode( - Hex.toStringCondensed(packKey), - StandardCharsets.UTF_8)).toString(); + "pack_id=" + + URLEncoder.encode(Hex.toStringCondensed(packId.serialize()), StandardCharsets.UTF_8) + + "&pack_key=" + + URLEncoder.encode(Hex.toStringCondensed(packKey), StandardCharsets.UTF_8)).toString(); } catch (URISyntaxException e) { throw new AssertionError(e); } @@ -1939,6 +1952,7 @@ public class Manager implements Closeable { sticker = new Sticker(stickerPackId, messageSticker.getPackKey()); account.getStickerStore().updateSticker(sticker); } + enqueueJob(new RetrieveStickerPackJob(stickerPackId, messageSticker.getPackKey())); } return actions; } @@ -2014,6 +2028,9 @@ public class Manager implements Closeable { try { action.execute(this); } catch (Throwable e) { + if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } logger.warn("Message action failed.", e); } } @@ -2060,7 +2077,7 @@ public class Manager implements Closeable { boolean returnOnTimeout, boolean ignoreAttachments, ReceiveMessageHandler handler - ) throws IOException { + ) throws IOException, InterruptedException { retryFailedReceivedMessages(handler, ignoreAttachments); Set queuedActions = null; @@ -2069,7 +2086,7 @@ public class Manager implements Closeable { var hasCaughtUpWithOldMessages = false; - while (true) { + while (!Thread.interrupted()) { SignalServiceEnvelope envelope; SignalServiceContent content = null; Exception exception = null; @@ -2096,6 +2113,9 @@ public class Manager implements Closeable { try { action.execute(this); } catch (Throwable e) { + if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } logger.warn("Message action failed.", e); } } @@ -2106,6 +2126,12 @@ public class Manager implements Closeable { // Continue to wait another timeout for new messages continue; } + } catch (AssertionError e) { + if (e.getCause() instanceof InterruptedException) { + throw (InterruptedException) e.getCause(); + } else { + throw e; + } } catch (TimeoutException e) { if (returnOnTimeout) return; continue; @@ -2139,6 +2165,9 @@ public class Manager implements Closeable { try { action.execute(this); } catch (Throwable e) { + if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } logger.warn("Message action failed.", e); } } @@ -2461,16 +2490,23 @@ public class Manager implements Closeable { continue; } final var stickerPackId = StickerPackId.deserialize(m.getPackId().get()); + final var installed = !m.getType().isPresent() + || m.getType().get() == StickerPackOperationMessage.Type.INSTALL; + var sticker = account.getStickerStore().getSticker(stickerPackId); - if (sticker == null) { - if (!m.getPackKey().isPresent()) { - continue; + if (m.getPackKey().isPresent()) { + if (sticker == null) { + sticker = new Sticker(stickerPackId, m.getPackKey().get()); + } + if (installed) { + enqueueJob(new RetrieveStickerPackJob(stickerPackId, m.getPackKey().get())); } - sticker = new Sticker(stickerPackId, m.getPackKey().get()); } - sticker.setInstalled(!m.getType().isPresent() - || m.getType().get() == StickerPackOperationMessage.Type.INSTALL); - account.getStickerStore().updateSticker(sticker); + + if (sticker != null) { + sticker.setInstalled(installed); + account.getStickerStore().updateSticker(sticker); + } } } if (syncMessage.getFetchType().isPresent()) { @@ -2528,6 +2564,9 @@ public class Manager implements Closeable { avatarStore.storeProfileAvatar(address, outputStream -> retrieveProfileAvatar(avatarPath, profileKey, outputStream)); } catch (Throwable e) { + if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } logger.warn("Failed to download profile avatar, ignoring: {}", e.getMessage()); } } @@ -2939,6 +2978,11 @@ public class Manager implements Closeable { return account.getRecipientStore().resolveRecipientTrusted(address); } + private void enqueueJob(Job job) { + var context = new Context(account, accountManager, messageReceiver, stickerPackStore); + job.run(context); + } + @Override public void close() throws IOException { close(true);