Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.annimon.stream.Stream
import com.bumptech.glide.Glide
import com.squareup.phrase.Phrase
import dagger.Lazy
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.lifecycle.withCreationCallback
import kotlinx.coroutines.CancellationException
Expand Down Expand Up @@ -261,7 +262,6 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
@Inject lateinit var typingStatusRepository: TypingStatusRepository
@Inject lateinit var typingStatusSender: TypingStatusSender
@Inject lateinit var openGroupManager: OpenGroupManager
@Inject lateinit var attachmentDatabase: AttachmentDatabase
@Inject lateinit var clock: SnodeClock
@Inject lateinit var messageSender: MessageSender
@Inject lateinit var resendMessageUtilities: ResendMessageUtilities
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package org.thoughtcrime.securesms.conversation.v2.input_bar.mentions

import android.view.View
import network.loki.messenger.databinding.ViewMentionCandidateV2Binding
import org.thoughtcrime.securesms.conversation.v2.mention.MentionViewModel
import org.thoughtcrime.securesms.ui.components.Avatar
import org.thoughtcrime.securesms.ui.setThemedContent
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
import org.thoughtcrime.securesms.util.AvatarBadge

fun ViewMentionCandidateV2Binding.update(candidate: MentionViewModel.Candidate) {
mentionCandidateNameTextView.text = candidate.nameHighlighted
profilePictureView.setThemedContent {
Avatar(
size = LocalDimensions.current.iconMediumAvatar,
data = candidate.member.avatarData,
badge = if (candidate.member.showAdminCrown) AvatarBadge.Admin else AvatarBadge.None
)
}

moderatorIconImageView.visibility = if (candidate.member.showAdminCrown) View.VISIBLE else View.GONE
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import org.thoughtcrime.securesms.ui.theme.LocalColors
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
import org.thoughtcrime.securesms.ui.theme.LocalType
import org.thoughtcrime.securesms.ui.theme.bold
import org.thoughtcrime.securesms.util.AvatarBadge
import org.thoughtcrime.securesms.util.AvatarUtils
import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.disableClipping
Expand Down Expand Up @@ -175,7 +176,6 @@ class VisibleMessageView : FrameLayout {
val isStartOfMessageCluster = isStartOfMessageCluster(message, previous, isGroupThread)
val isEndOfMessageCluster = isEndOfMessageCluster(message, next, isGroupThread)
// Show profile picture and sender name if this is a group thread AND the message is incoming
binding.moderatorIconImageView.isVisible = false
binding.profilePictureView.visibility = when {
threadRecipient.isGroupOrCommunityRecipient && !message.isOutgoing && isEndOfMessageCluster -> View.VISIBLE
threadRecipient.isGroupOrCommunityRecipient -> View.INVISIBLE
Expand All @@ -199,22 +199,22 @@ class VisibleMessageView : FrameLayout {

if (isGroupThread && !message.isOutgoing) {
if (isEndOfMessageCluster) {
val showProBadge = if (sender.address is Address.WithAccountId) {
(threadRecipient.data as? RecipientData.GroupLike)
?.shouldShowAdminCrown(sender.address.accountId) == true
} else {
false
}
binding.profilePictureView.setThemedContent {
Avatar(
size = LocalDimensions.current.iconMediumAvatar,
data = avatarUtils.getUIDataFromRecipient(sender),
badge = if(showProBadge) AvatarBadge.Admin else AvatarBadge.None,
modifier = Modifier.clickable {
delegate?.showUserProfileModal(message.recipient)
}
)
}

binding.moderatorIconImageView.isVisible = if (sender.address is Address.WithAccountId) {
(threadRecipient.data as? RecipientData.GroupLike)
?.shouldShowAdminCrown(sender.address.accountId) == true
} else {
false
}
}
}
if(!message.isOutgoing && (isStartOfMessageCluster && isGroupThread)){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,16 @@
import android.text.TextUtils;
import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.bumptech.glide.Glide;

import net.zetetic.database.sqlcipher.SQLiteDatabase;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId;
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState;
Expand Down Expand Up @@ -80,14 +79,19 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;

import dagger.Lazy;
import dagger.hilt.android.qualifiers.ApplicationContext;
import kotlin.jvm.Synchronized;
import kotlinx.coroutines.channels.BufferOverflow;
import kotlinx.coroutines.flow.MutableSharedFlow;
import kotlinx.coroutines.flow.SharedFlow;
import kotlinx.coroutines.flow.SharedFlowKt;

@Singleton
public class AttachmentDatabase extends Database {

private static final String TAG = AttachmentDatabase.class.getSimpleName();
Expand Down Expand Up @@ -161,13 +165,18 @@ public class AttachmentDatabase extends Database {

final ExecutorService thumbnailExecutor = Util.newSingleThreadedLifoExecutor();

private final AttachmentSecret attachmentSecret;
private final Lazy<@NonNull AttachmentSecret> attachmentSecret;

private final MutableSharedFlow<Object> mutableChangesNotification = SharedFlowKt.MutableSharedFlow(
0, 100, BufferOverflow.DROP_OLDEST
);

public AttachmentDatabase(Context context, Provider<SQLCipherOpenHelper> databaseHelper, AttachmentSecret attachmentSecret) {
@Inject
public AttachmentDatabase(
@ApplicationContext Context context,
Provider<SQLCipherOpenHelper> databaseHelper,
Lazy<@NonNull AttachmentSecret> attachmentSecret
) {
super(context, databaseHelper);
this.attachmentSecret = attachmentSecret;
}
Expand Down Expand Up @@ -535,9 +544,9 @@ public void setTransferState(@NonNull AttachmentId attachmentId, int transferSta

try {
if (dataInfo.random != null && dataInfo.random.length == 32) {
return ModernDecryptingPartInputStream.createFor(attachmentSecret, dataInfo.random, dataInfo.file, offset);
return ModernDecryptingPartInputStream.createFor(attachmentSecret.get(), dataInfo.random, dataInfo.file, offset);
} else {
InputStream stream = ClassicDecryptingPartInputStream.createFor(attachmentSecret, dataInfo.file);
InputStream stream = ClassicDecryptingPartInputStream.createFor(attachmentSecret.get(), dataInfo.file);
long skipped = stream.skip(offset);

if (skipped != offset) {
Expand Down Expand Up @@ -607,7 +616,7 @@ public void setTransferState(@NonNull AttachmentId attachmentId, int transferSta
File dataFile = File.createTempFile("part", ".mms", partsDirectory);

Log.d("AttachmentDatabase", "Writing attachment data to: " + dataFile.getAbsolutePath());
Pair<byte[], OutputStream> out = ModernEncryptingPartOutputStream.createFor(attachmentSecret, dataFile, false);
Pair<byte[], OutputStream> out = ModernEncryptingPartOutputStream.createFor(attachmentSecret.get(), dataFile, false);
long length = Util.copy(in, out.second);

return new DataInfo(dataFile, length, out.first);
Expand Down Expand Up @@ -894,7 +903,7 @@ private ThumbnailData generateVideoThumbnail(AttachmentId attachmentId) {
return null;
}

EncryptedMediaDataSource dataSource = new EncryptedMediaDataSource(attachmentSecret, dataInfo.file, dataInfo.random, dataInfo.length);
EncryptedMediaDataSource dataSource = new EncryptedMediaDataSource(attachmentSecret.get(), dataInfo.file, dataInfo.random, dataInfo.length);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(dataSource);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ object DatabaseModule {
return manager.openHelper
}

@Provides
@Singleton
fun provideAttachmentDatabase(@ApplicationContext context: Context,
openHelper: Provider<SQLCipherOpenHelper>,
attachmentSecret: AttachmentSecret) = AttachmentDatabase(context, openHelper, attachmentSecret)
@Provides
@Singleton
fun provideMediaDatbase(@ApplicationContext context: Context, openHelper: Provider<SQLCipherOpenHelper>) = MediaDatabase(context, openHelper)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@


import android.graphics.Bitmap;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsignal.utilities.Log;

import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.ResourceDecoder;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;

import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -20,10 +23,10 @@ public class EncryptedBitmapCacheDecoder extends EncryptedCoder implements Resou
private static final String TAG = EncryptedBitmapCacheDecoder.class.getSimpleName();

private final StreamBitmapDecoder streamBitmapDecoder;
private final byte[] secret;
private final AttachmentSecretProvider attachmentSecretProvider;

public EncryptedBitmapCacheDecoder(@NonNull byte[] secret, @NonNull StreamBitmapDecoder streamBitmapDecoder) {
this.secret = secret;
public EncryptedBitmapCacheDecoder(@NonNull AttachmentSecretProvider attachmentSecretProvider, @NonNull StreamBitmapDecoder streamBitmapDecoder) {
this.attachmentSecretProvider = attachmentSecretProvider;
this.streamBitmapDecoder = streamBitmapDecoder;
}

Expand All @@ -33,7 +36,7 @@ public boolean handles(@NonNull File source, @NonNull Options options)
{
Log.i(TAG, "Checking item for encrypted Bitmap cache decoder: " + source.toString());

try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
try (InputStream inputStream = createEncryptedInputStream(attachmentSecretProvider.getOrCreateAttachmentSecret().getModernKey(), source)) {
return streamBitmapDecoder.handles(inputStream, options);
} catch (IOException e) {
Log.w(TAG, e);
Expand All @@ -47,7 +50,7 @@ public Resource<Bitmap> decode(@NonNull File source, int width, int height, @Non
throws IOException
{
Log.i(TAG, "Encrypted Bitmap cache decoder running: " + source.toString());
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
try (InputStream inputStream = createEncryptedInputStream(attachmentSecretProvider.getOrCreateAttachmentSecret().getModernKey(), source)) {
return streamBitmapDecoder.decode(inputStream, width, height, options);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;

import com.bumptech.glide.load.EncodeStrategy;
import com.bumptech.glide.load.Options;
Expand All @@ -19,10 +20,10 @@ public class EncryptedBitmapResourceEncoder extends EncryptedCoder implements Re

private static final String TAG = EncryptedBitmapResourceEncoder.class.getSimpleName();

private final byte[] secret;
private final AttachmentSecretProvider secretProvider;

public EncryptedBitmapResourceEncoder(@NonNull byte[] secret) {
this.secret = secret;
public EncryptedBitmapResourceEncoder(@NonNull AttachmentSecretProvider secretProvider) {
this.secretProvider = secretProvider;
}

@Override
Expand All @@ -39,7 +40,7 @@ public boolean encode(@NonNull Resource<Bitmap> data, @NonNull File file, @NonNu
Bitmap.CompressFormat format = getFormat(bitmap, options);
int quality = options.get(BitmapEncoder.COMPRESSION_QUALITY);

try (OutputStream os = createEncryptedOutputStream(secret, file)) {
try (OutputStream os = createEncryptedOutputStream(secretProvider.getOrCreateAttachmentSecret().getModernKey(), file)) {
bitmap.compress(format, quality, os);
os.close();
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
package org.thoughtcrime.securesms.glide.cache;


import androidx.annotation.NonNull;

import com.bumptech.glide.load.Encoder;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;

import org.jspecify.annotations.NonNull;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import dagger.Lazy;

public class EncryptedCacheEncoder extends EncryptedCoder implements Encoder<InputStream> {

private static final String TAG = EncryptedCacheEncoder.class.getSimpleName();

private final byte[] secret;
private final AttachmentSecretProvider attachmentSecretProvider;
private final ArrayPool byteArrayPool;

public EncryptedCacheEncoder(@NonNull byte[] secret, @NonNull ArrayPool byteArrayPool) {
this.secret = secret;
public EncryptedCacheEncoder(AttachmentSecretProvider attachmentSecretProvider, @NonNull ArrayPool byteArrayPool) {
this.attachmentSecretProvider = attachmentSecretProvider;
this.byteArrayPool = byteArrayPool;
}

Expand All @@ -33,7 +36,7 @@ public boolean encode(@NonNull InputStream data, @NonNull File file, @NonNull Op

byte[] buffer = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class);

try (OutputStream outputStream = createEncryptedOutputStream(secret, file)) {
try (OutputStream outputStream = createEncryptedOutputStream(attachmentSecretProvider.getOrCreateAttachmentSecret().getModernKey(), file)) {
int read;

while ((read = data.read(buffer)) != -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;

import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.ResourceDecoder;
Expand All @@ -19,19 +20,19 @@ public class EncryptedGifCacheDecoder extends EncryptedCoder implements Resource

private static final String TAG = EncryptedGifCacheDecoder.class.getSimpleName();

private final byte[] secret;
private final AttachmentSecretProvider attachmentSecretProvider;
private final StreamGifDecoder gifDecoder;

public EncryptedGifCacheDecoder(@NonNull byte[] secret, @NonNull StreamGifDecoder gifDecoder) {
this.secret = secret;
public EncryptedGifCacheDecoder(@NonNull AttachmentSecretProvider attachmentSecretProvider, @NonNull StreamGifDecoder gifDecoder) {
this.attachmentSecretProvider = attachmentSecretProvider;
this.gifDecoder = gifDecoder;
}

@Override
public boolean handles(@NonNull File source, @NonNull Options options) {
Log.i(TAG, "Checking item for encrypted GIF cache decoder: " + source.toString());

try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
try (InputStream inputStream = createEncryptedInputStream(attachmentSecretProvider.getOrCreateAttachmentSecret().getModernKey(), source)) {
return gifDecoder.handles(inputStream, options);
} catch (IOException e) {
Log.w(TAG, e);
Expand All @@ -43,7 +44,7 @@ public boolean handles(@NonNull File source, @NonNull Options options) {
@Override
public Resource<GifDrawable> decode(@NonNull File source, int width, int height, @NonNull Options options) throws IOException {
Log.i(TAG, "Encrypted GIF cache decoder running...");
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
try (InputStream inputStream = createEncryptedInputStream(attachmentSecretProvider.getOrCreateAttachmentSecret().getModernKey(), source)) {
return gifDecoder.decode(inputStream, width, height, options);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import androidx.annotation.NonNull;
import org.session.libsignal.utilities.Log;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;

import com.bumptech.glide.load.EncodeStrategy;
import com.bumptech.glide.load.Options;
Expand All @@ -19,10 +20,10 @@ public class EncryptedGifDrawableResourceEncoder extends EncryptedCoder implemen

private static final String TAG = EncryptedGifDrawableResourceEncoder.class.getSimpleName();

private final byte[] secret;
private final AttachmentSecretProvider secretProvider;

public EncryptedGifDrawableResourceEncoder(@NonNull byte[] secret) {
this.secret = secret;
public EncryptedGifDrawableResourceEncoder(@NonNull AttachmentSecretProvider secretProvider) {
this.secretProvider = secretProvider;
}

@Override
Expand All @@ -34,7 +35,7 @@ public EncodeStrategy getEncodeStrategy(@NonNull Options options) {
public boolean encode(@NonNull Resource<GifDrawable> data, @NonNull File file, @NonNull Options options) {
GifDrawable drawable = data.get();

try (OutputStream outputStream = createEncryptedOutputStream(secret, file)) {
try (OutputStream outputStream = createEncryptedOutputStream(secretProvider.getOrCreateAttachmentSecret().getModernKey(), file)) {
ByteBufferUtil.toStream(drawable.getBuffer(), outputStream);
return true;
} catch (IOException e) {
Expand Down
Loading