Make attachment count/size remote configurable.

This commit is contained in:
Greyson Parrelli
2023-05-18 21:19:04 -04:00
committed by Nicholas Tinsley
parent 938c82be3f
commit 4d6d31d624
5 changed files with 34 additions and 11 deletions

View File

@@ -30,6 +30,8 @@ import org.thoughtcrime.securesms.s3.S3;
import org.thoughtcrime.securesms.transport.RetryLaterException; import org.thoughtcrime.securesms.transport.RetryLaterException;
import org.thoughtcrime.securesms.util.AttachmentUtil; import org.thoughtcrime.securesms.util.AttachmentUtil;
import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.Base64;
import org.thoughtcrime.securesms.util.ByteUnit;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
@@ -54,9 +56,11 @@ public final class AttachmentDownloadJob extends BaseJob {
public static final String KEY = "AttachmentDownloadJob"; public static final String KEY = "AttachmentDownloadJob";
private static final int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024;
private static final String TAG = Log.tag(AttachmentDownloadJob.class); private static final String TAG = Log.tag(AttachmentDownloadJob.class);
/** A little extra allowed size to account for any adjustments made by other clients */
private static final int MAX_ATTACHMENT_SIZE_BUFFER = 25 * 1024 * 1024;
private static final String KEY_MESSAGE_ID = "message_id"; private static final String KEY_MESSAGE_ID = "message_id";
private static final String KEY_PART_ROW_ID = "part_row_id"; private static final String KEY_PART_ROW_ID = "part_row_id";
private static final String KEY_PAR_UNIQUE_ID = "part_unique_id"; private static final String KEY_PAR_UNIQUE_ID = "part_unique_id";
@@ -191,7 +195,10 @@ public final class AttachmentDownloadJob extends BaseJob {
try { try {
SignalServiceMessageReceiver messageReceiver = ApplicationDependencies.getSignalServiceMessageReceiver(); SignalServiceMessageReceiver messageReceiver = ApplicationDependencies.getSignalServiceMessageReceiver();
SignalServiceAttachmentPointer pointer = createAttachmentPointer(attachment); SignalServiceAttachmentPointer pointer = createAttachmentPointer(attachment);
InputStream stream = messageReceiver.retrieveAttachment(pointer, attachmentFile, MAX_ATTACHMENT_SIZE, (total, progress) -> EventBus.getDefault().postSticky(new PartProgressEvent(attachment, PartProgressEvent.Type.NETWORK, total, progress))); InputStream stream = messageReceiver.retrieveAttachment(pointer,
attachmentFile,
ByteUnit.MEGABYTES.toBytes(FeatureFlags.maxAttachmentSizeMb()) + MAX_ATTACHMENT_SIZE_BUFFER,
(total, progress) -> EventBus.getDefault().postSticky(new PartProgressEvent(attachment, PartProgressEvent.Type.NETWORK, total, progress)));
database.insertAttachmentsForPlaceholder(messageId, attachmentId, stream); database.insertAttachmentsForPlaceholder(messageId, attachmentId, stream);
} catch (RangeException e) { } catch (RangeException e) {

View File

@@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.mediasend.MediaSendConstants
import org.thoughtcrime.securesms.mms.SentMediaQuality import org.thoughtcrime.securesms.mms.SentMediaQuality
import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.stories.Stories import org.thoughtcrime.securesms.stories.Stories
import org.thoughtcrime.securesms.util.FeatureFlags
data class MediaSelectionState( data class MediaSelectionState(
val sendType: MessageSendType, val sendType: MessageSendType,
@@ -31,7 +32,7 @@ data class MediaSelectionState(
val maxSelection = if (sendType.usesSmsTransport) { val maxSelection = if (sendType.usesSmsTransport) {
MediaSendConstants.MAX_SMS MediaSendConstants.MAX_SMS
} else { } else {
MediaSendConstants.MAX_PUSH FeatureFlags.maxAttachmentCount()
} }
val canSend = !isSent && selectedMedia.isNotEmpty() val canSend = !isSent && selectedMedia.isNotEmpty()

View File

@@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.attachments.PointerAttachment
import org.thoughtcrime.securesms.database.model.StoryType import org.thoughtcrime.securesms.database.model.StoryType
import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.stickers.StickerLocator import org.thoughtcrime.securesms.stickers.StickerLocator
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
import org.whispersystems.signalservice.api.InvalidMessageStructureException import org.whispersystems.signalservice.api.InvalidMessageStructureException
import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata import org.whispersystems.signalservice.api.crypto.EnvelopeMetadata
@@ -31,8 +32,6 @@ private val ByteString.isNotEmpty: Boolean
object SignalServiceProtoUtil { object SignalServiceProtoUtil {
const val MAX_ALLOWED_ATTACHMENTS = 100
/** Contains some user data that affects the conversation */ /** Contains some user data that affects the conversation */
val DataMessage.hasRenderableContent: Boolean val DataMessage.hasRenderableContent: Boolean
get() { get() {
@@ -161,7 +160,7 @@ object SignalServiceProtoUtil {
} }
fun List<AttachmentPointer>.toPointersWithinLimit(): List<Attachment> { fun List<AttachmentPointer>.toPointersWithinLimit(): List<Attachment> {
return mapNotNull { it.toPointer() }.take(MAX_ALLOWED_ATTACHMENTS) return mapNotNull { it.toPointer() }.take(FeatureFlags.maxAttachmentCount())
} }
fun AttachmentPointer.toPointer(stickerLocator: StickerLocator? = null): Attachment? { fun AttachmentPointer.toPointer(stickerLocator: StickerLocator? = null): Attachment? {

View File

@@ -17,9 +17,9 @@ import org.thoughtcrime.securesms.attachments.UriAttachment
import org.thoughtcrime.securesms.conversation.MessageSendType import org.thoughtcrime.securesms.conversation.MessageSendType
import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.mediasend.Media
import org.thoughtcrime.securesms.mediasend.MediaSendConstants
import org.thoughtcrime.securesms.mms.MediaConstraints import org.thoughtcrime.securesms.mms.MediaConstraints
import org.thoughtcrime.securesms.providers.BlobProvider import org.thoughtcrime.securesms.providers.BlobProvider
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.UriUtil import org.thoughtcrime.securesms.util.UriUtil
import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.Util
@@ -91,7 +91,7 @@ class ShareRepository(context: Context) {
} }
val media: List<Media> = mimeTypes.toList() val media: List<Media> = mimeTypes.toList()
.take(MediaSendConstants.MAX_PUSH) .take(FeatureFlags.maxAttachmentCount())
.map { (uri, mimeType) -> .map { (uri, mimeType) ->
val stream: InputStream = try { val stream: InputStream = try {
appContext.contentResolver.openInputStream(uri) appContext.contentResolver.openInputStream(uri)

View File

@@ -108,6 +108,8 @@ public final class FeatureFlags {
private static final String EDIT_MESSAGE_RECEIVE = "android.editMessage.receive"; private static final String EDIT_MESSAGE_RECEIVE = "android.editMessage.receive";
private static final String EDIT_MESSAGE_SEND = "android.editMessage.send"; private static final String EDIT_MESSAGE_SEND = "android.editMessage.send";
private static final String CALL_DELETE_SYNC = "android.calling.deleteSync"; private static final String CALL_DELETE_SYNC = "android.calling.deleteSync";
private static final String MAX_ATTACHMENT_COUNT = "android.attachments.maxCount";
private static final String MAX_ATTACHMENT_SIZE_MB = "android.attachments.maxSize";
/** /**
* We will only store remote values for flags in this set. If you want a flag to be controllable * We will only store remote values for flags in this set. If you want a flag to be controllable
@@ -166,7 +168,9 @@ public final class FeatureFlags {
TEXT_FORMATTING, TEXT_FORMATTING,
ANY_ADDRESS_PORTS_KILL_SWITCH, ANY_ADDRESS_PORTS_KILL_SWITCH,
EDIT_MESSAGE_RECEIVE, EDIT_MESSAGE_RECEIVE,
EDIT_MESSAGE_SEND EDIT_MESSAGE_SEND,
MAX_ATTACHMENT_COUNT,
MAX_ATTACHMENT_SIZE_MB
); );
@VisibleForTesting @VisibleForTesting
@@ -233,7 +237,9 @@ public final class FeatureFlags {
CDS_HARD_LIMIT, CDS_HARD_LIMIT,
TEXT_FORMATTING, TEXT_FORMATTING,
EDIT_MESSAGE_RECEIVE, EDIT_MESSAGE_RECEIVE,
EDIT_MESSAGE_SEND EDIT_MESSAGE_SEND,
MAX_ATTACHMENT_COUNT,
MAX_ATTACHMENT_SIZE_MB
); );
/** /**
@@ -609,6 +615,16 @@ public final class FeatureFlags {
return getBoolean(CALL_DELETE_SYNC, false); return getBoolean(CALL_DELETE_SYNC, false);
} }
/** Maximum number of attachments allowed to be sent/received. */
public static int maxAttachmentCount() {
return getInteger(MAX_ATTACHMENT_COUNT, 32);
}
/** Maximum attachment size, in mebibytes. */
public static int maxAttachmentSizeMb() {
return getInteger(MAX_ATTACHMENT_SIZE_MB, 100);
}
/** Only for rendering debug info. */ /** Only for rendering debug info. */
public static synchronized @NonNull Map<String, Object> getMemoryValues() { public static synchronized @NonNull Map<String, Object> getMemoryValues() {
return new TreeMap<>(REMOTE_VALUES); return new TreeMap<>(REMOTE_VALUES);