Search in sources :

Example 6 with SignalServiceMessageReceiver

use of org.whispersystems.signalservice.api.SignalServiceMessageReceiver in project Signal-Android by signalapp.

the class AvatarGroupsV2DownloadJob method downloadGroupAvatarBytes.

@Nullable
public static byte[] downloadGroupAvatarBytes(@NonNull Context context, @NonNull GroupMasterKey groupMasterKey, @NonNull String cdnKey) throws IOException {
    if (cdnKey.length() == 0) {
        return null;
    }
    GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
    File attachment = File.createTempFile("avatar", "gv2", context.getCacheDir());
    attachment.deleteOnExit();
    SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
    byte[] encryptedData;
    try (FileInputStream inputStream = receiver.retrieveGroupsV2ProfileAvatar(cdnKey, attachment, AVATAR_DOWNLOAD_FAIL_SAFE_MAX_SIZE)) {
        encryptedData = new byte[(int) attachment.length()];
        StreamUtil.readFully(inputStream, encryptedData);
        GroupsV2Operations operations = ApplicationDependencies.getGroupsV2Operations();
        GroupsV2Operations.GroupOperations groupOperations = operations.forGroup(groupSecretParams);
        return groupOperations.decryptAvatar(encryptedData);
    } finally {
        if (attachment.exists())
            if (!attachment.delete()) {
                Log.w(TAG, "Unable to delete temp avatar file");
            }
    }
}
Also used : GroupsV2Operations(org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations) GroupSecretParams(org.signal.zkgroup.groups.GroupSecretParams) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) File(java.io.File) FileInputStream(java.io.FileInputStream) Nullable(androidx.annotation.Nullable)

Example 7 with SignalServiceMessageReceiver

use of org.whispersystems.signalservice.api.SignalServiceMessageReceiver in project Signal-Android by signalapp.

the class AvatarGroupsV1DownloadJob method onRun.

@Override
public void onRun() throws IOException {
    GroupDatabase database = SignalDatabase.groups();
    Optional<GroupRecord> record = database.getGroup(groupId);
    File attachment = null;
    try {
        if (record.isPresent()) {
            long avatarId = record.get().getAvatarId();
            String contentType = record.get().getAvatarContentType();
            byte[] key = record.get().getAvatarKey();
            String relay = record.get().getRelay();
            Optional<byte[]> digest = Optional.fromNullable(record.get().getAvatarDigest());
            Optional<String> fileName = Optional.absent();
            if (avatarId == -1 || key == null) {
                return;
            }
            if (digest.isPresent()) {
                Log.i(TAG, "Downloading group avatar with digest: " + Hex.toString(digest.get()));
            }
            attachment = File.createTempFile("avatar", "tmp", context.getCacheDir());
            attachment.deleteOnExit();
            SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
            SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(0, new SignalServiceAttachmentRemoteId(avatarId), contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, false, false, Optional.absent(), Optional.absent(), System.currentTimeMillis());
            InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);
            AvatarHelper.setAvatar(context, record.get().getRecipientId(), inputStream);
            SignalDatabase.groups().onAvatarUpdated(groupId, true);
            inputStream.close();
        }
    } catch (NonSuccessfulResponseCodeException | InvalidMessageException | MissingConfigurationException e) {
        Log.w(TAG, e);
    } finally {
        if (attachment != null)
            attachment.delete();
    }
}
Also used : InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) InputStream(java.io.InputStream) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) NonSuccessfulResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) MissingConfigurationException(org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) SignalServiceAttachmentRemoteId(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) File(java.io.File)

Example 8 with SignalServiceMessageReceiver

use of org.whispersystems.signalservice.api.SignalServiceMessageReceiver in project Signal-Android by WhisperSystems.

the class StickerDownloadJob method onRun.

@Override
protected void onRun() throws Exception {
    StickerDatabase db = SignalDatabase.stickers();
    StickerRecord stickerRecord = db.getSticker(sticker.getPackId(), sticker.getStickerId(), sticker.isCover());
    if (stickerRecord != null) {
        try (InputStream stream = PartAuthority.getAttachmentStream(context, stickerRecord.getUri())) {
            if (stream != null) {
                Log.w(TAG, "Sticker already downloaded.");
                return;
            }
        } catch (FileNotFoundException e) {
            Log.w(TAG, "Sticker file no longer exists, downloading again.");
        }
    }
    if (!db.isPackInstalled(sticker.getPackId()) && !sticker.isCover()) {
        Log.w(TAG, "Pack is no longer installed.");
        return;
    }
    SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
    byte[] packIdBytes = Hex.fromStringCondensed(sticker.getPackId());
    byte[] packKeyBytes = Hex.fromStringCondensed(sticker.getPackKey());
    InputStream stream = receiver.retrieveSticker(packIdBytes, packKeyBytes, sticker.getStickerId());
    db.insertSticker(sticker, stream, notify);
}
Also used : InputStream(java.io.InputStream) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) StickerDatabase(org.thoughtcrime.securesms.database.StickerDatabase) FileNotFoundException(java.io.FileNotFoundException) StickerRecord(org.thoughtcrime.securesms.database.model.StickerRecord)

Example 9 with SignalServiceMessageReceiver

use of org.whispersystems.signalservice.api.SignalServiceMessageReceiver in project Signal-Android by WhisperSystems.

the class LinkPreviewRepository method fetchStickerPackLinkPreview.

private static RequestController fetchStickerPackLinkPreview(@NonNull Context context, @NonNull String packUrl, @NonNull Callback callback) {
    SignalExecutors.UNBOUNDED.execute(() -> {
        try {
            Pair<String, String> stickerParams = StickerUrl.parseShareLink(packUrl).or(new Pair<>("", ""));
            String packIdString = stickerParams.first();
            String packKeyString = stickerParams.second();
            byte[] packIdBytes = Hex.fromStringCondensed(packIdString);
            byte[] packKeyBytes = Hex.fromStringCondensed(packKeyString);
            SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
            SignalServiceStickerManifest manifest = receiver.retrieveStickerManifest(packIdBytes, packKeyBytes);
            String title = manifest.getTitle().or(manifest.getAuthor()).or("");
            Optional<StickerInfo> firstSticker = Optional.fromNullable(manifest.getStickers().size() > 0 ? manifest.getStickers().get(0) : null);
            Optional<StickerInfo> cover = manifest.getCover().or(firstSticker);
            if (cover.isPresent()) {
                Bitmap bitmap = GlideApp.with(context).asBitmap().load(new StickerRemoteUri(packIdString, packKeyString, cover.get().getId())).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).centerInside().submit(512, 512).get();
                Optional<Attachment> thumbnail = bitmapToAttachment(bitmap, Bitmap.CompressFormat.WEBP, MediaUtil.IMAGE_WEBP);
                callback.onSuccess(new LinkPreview(packUrl, title, "", 0, thumbnail));
            } else {
                callback.onError(Error.PREVIEW_NOT_AVAILABLE);
            }
        } catch (IOException | InvalidMessageException | ExecutionException | InterruptedException e) {
            Log.w(TAG, "Failed to fetch sticker pack link preview.");
            callback.onError(Error.PREVIEW_NOT_AVAILABLE);
        }
    });
    return () -> Log.i(TAG, "Cancelled sticker pack link preview fetch -- no effect.");
}
Also used : SignalServiceStickerManifest(org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest) InvalidMessageException(org.whispersystems.libsignal.InvalidMessageException) StickerRemoteUri(org.thoughtcrime.securesms.stickers.StickerRemoteUri) Attachment(org.thoughtcrime.securesms.attachments.Attachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) IOException(java.io.IOException) Bitmap(android.graphics.Bitmap) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) StickerInfo(org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest.StickerInfo) ExecutionException(java.util.concurrent.ExecutionException)

Example 10 with SignalServiceMessageReceiver

use of org.whispersystems.signalservice.api.SignalServiceMessageReceiver in project Signal-Android by WhisperSystems.

the class RetrieveProfileAvatarJob method onRun.

@Override
public void onRun() throws IOException {
    RecipientDatabase database = SignalDatabase.recipients();
    ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.resolve().getProfileKey());
    if (profileKey == null) {
        Log.w(TAG, "Recipient profile key is gone!");
        return;
    }
    if (Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
        Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
        return;
    }
    if (TextUtils.isEmpty(profileAvatar)) {
        Log.w(TAG, "Removing profile avatar (no url) for: " + recipient.getId().serialize());
        AvatarHelper.delete(context, recipient.getId());
        database.setProfileAvatar(recipient.getId(), profileAvatar);
        return;
    }
    File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
    try {
        SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
        InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);
        try {
            AvatarHelper.setAvatar(context, recipient.getId(), avatarStream);
            if (recipient.isSelf()) {
                SignalStore.misc().markHasEverHadAnAvatar();
            }
        } catch (AssertionError e) {
            throw new IOException("Failed to copy stream. Likely a Conscrypt issue.", e);
        }
    } catch (PushNetworkException e) {
        if (e.getCause() instanceof NonSuccessfulResponseCodeException) {
            Log.w(TAG, "Removing profile avatar (no image available) for: " + recipient.getId().serialize());
            AvatarHelper.delete(context, recipient.getId());
        } else {
            throw e;
        }
    } finally {
        if (downloadDestination != null)
            downloadDestination.delete();
    }
    database.setProfileAvatar(recipient.getId(), profileAvatar);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) InputStream(java.io.InputStream) NonSuccessfulResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException) IOException(java.io.IOException) File(java.io.File) ProfileKey(org.signal.zkgroup.profiles.ProfileKey)

Aggregations

SignalServiceMessageReceiver (org.whispersystems.signalservice.api.SignalServiceMessageReceiver)16 File (java.io.File)8 InputStream (java.io.InputStream)8 IOException (java.io.IOException)6 InvalidMessageException (org.whispersystems.libsignal.InvalidMessageException)6 NonSuccessfulResponseCodeException (org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException)6 StickerDatabase (org.thoughtcrime.securesms.database.StickerDatabase)4 SignalServiceAttachmentPointer (org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer)4 SignalServiceStickerManifest (org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest)4 StickerInfo (org.whispersystems.signalservice.api.messages.SignalServiceStickerManifest.StickerInfo)4 MissingConfigurationException (org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException)4 Bitmap (android.graphics.Bitmap)2 Nullable (androidx.annotation.Nullable)2 FileInputStream (java.io.FileInputStream)2 FileNotFoundException (java.io.FileNotFoundException)2 ArrayList (java.util.ArrayList)2 ExecutionException (java.util.concurrent.ExecutionException)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 GroupSecretParams (org.signal.zkgroup.groups.GroupSecretParams)2 ProfileKey (org.signal.zkgroup.profiles.ProfileKey)2