Fix transfer control progress reporting bugs.
This commit is contained in:
parent
3f682be609
commit
d22a2c0a50
@ -120,25 +120,13 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
}
|
||||
|
||||
if (event.type == PartProgressEvent.Type.COMPRESSION) {
|
||||
val mutableMap = it.compressionProgress.toMutableMap()
|
||||
val updateEvent = Progress.fromEvent(event)
|
||||
val existingEvent = mutableMap[attachment]
|
||||
if (existingEvent == null || updateEvent.completed > existingEvent.completed) {
|
||||
mutableMap[attachment] = updateEvent
|
||||
} else if (updateEvent.completed < 0.bytes) {
|
||||
mutableMap.remove(attachment)
|
||||
}
|
||||
return@updateState it.copy(compressionProgress = mutableMap.toMap())
|
||||
val progress = it.compressionProgress.toMutableMap()
|
||||
progress.applyProgress(attachment, Progress.fromEvent(event))
|
||||
return@updateState it.copy(compressionProgress = progress.toMap())
|
||||
} else {
|
||||
val mutableMap = it.networkProgress.toMutableMap()
|
||||
val updateEvent = Progress.fromEvent(event)
|
||||
val existingEvent = mutableMap[attachment]
|
||||
if (existingEvent == null || updateEvent.completed > existingEvent.completed) {
|
||||
mutableMap[attachment] = updateEvent
|
||||
} else if (updateEvent.completed < 0.bytes) {
|
||||
mutableMap.remove(attachment)
|
||||
}
|
||||
return@updateState it.copy(networkProgress = mutableMap.toMap())
|
||||
val progress = it.networkProgress.toMutableMap()
|
||||
progress.applyProgress(attachment, Progress.fromEvent(event))
|
||||
return@updateState it.copy(networkProgress = progress.toMap())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -227,6 +215,14 @@ class TransferControlView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
updateState { it.copy(isClickable = clickable) }
|
||||
}
|
||||
|
||||
private fun MutableMap<Attachment, Progress>.applyProgress(attachment: Attachment, update: Progress) {
|
||||
if (update.completed < 0.bytes) {
|
||||
remove(attachment)
|
||||
} else {
|
||||
put(attachment, update)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun verboseLog(message: () -> String) {
|
||||
if (VERBOSE_DEVELOPMENT_LOGGING) {
|
||||
Log.d(TAG, "[$viewId] ${message()}")
|
||||
|
||||
@ -11,6 +11,8 @@ import org.thoughtcrime.securesms.attachments.Attachment
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.mms.Slide
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
|
||||
|
||||
/**
|
||||
* Pure, Android-View-free logic for the transfer controls UI.
|
||||
@ -152,7 +154,7 @@ object TransferControls {
|
||||
} else if (state.isUpload) {
|
||||
ProgressLabel.Bytes(state.networkProgress.sumCompleted(), state.networkProgress.sumTotal())
|
||||
} else {
|
||||
val total = state.slides.sumOf { it.fileSize }.bytes
|
||||
val total = state.slides.sumOf { AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(it.fileSize)) }.bytes
|
||||
val completed = state.networkProgress.sumCompleted().let { if (it > total) total else it }
|
||||
ProgressLabel.Bytes(completed, total)
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ import org.thoughtcrime.securesms.attachments.Attachment
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable
|
||||
import org.thoughtcrime.securesms.mms.Slide
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
|
||||
|
||||
class TransferControlsTest {
|
||||
|
||||
@ -187,22 +189,24 @@ class TransferControlsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download label uses fixed slide size as denominator, not network total`() {
|
||||
fun `download label denominator is ciphertext size derived from slide, not network total`() {
|
||||
val slides = listOf(slide(AttachmentTable.TRANSFER_PROGRESS_STARTED, size = 1000))
|
||||
// Network total (2000) is intentionally larger than the slide's fixed file size (1000) to prove the denominator
|
||||
// comes from the slide size, which does not ramp up mid-transfer.
|
||||
// Completed is reported in ciphertext bytes, so the denominator must be the matching ciphertext length derived from the
|
||||
// slide's plaintext size. The network event's total (2000) is intentionally different to prove it is not the source.
|
||||
val state = stateOf(slides, networkProgress = progressOf(slides, completed = 500, total = 2000))
|
||||
val render = TransferControls.deriveRenderState(state) as TransferControlsRenderState.InProgress
|
||||
assertEquals(TransferControls.ProgressLabel.Bytes(500L.bytes, 1000L.bytes), render.label)
|
||||
val expectedTotal = AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(1000))
|
||||
assertEquals(TransferControls.ProgressLabel.Bytes(500L.bytes, expectedTotal.bytes), render.label)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `download label clamps completed to total`() {
|
||||
fun `download label clamps completed to ciphertext total`() {
|
||||
val slides = listOf(slide(AttachmentTable.TRANSFER_PROGRESS_STARTED, size = 1000))
|
||||
// Network bytes include encryption overhead, so completed can edge past the file size; it should clamp to total.
|
||||
val state = stateOf(slides, networkProgress = progressOf(slides, completed = 1100, total = 1100))
|
||||
val expectedTotal = AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(1000))
|
||||
// Incremental-MAC overhead means transmitted bytes can edge just past the computed ciphertext length; clamp to total.
|
||||
val state = stateOf(slides, networkProgress = progressOf(slides, completed = expectedTotal + 100, total = expectedTotal + 100))
|
||||
val render = TransferControls.deriveRenderState(state) as TransferControlsRenderState.InProgress
|
||||
assertEquals(TransferControls.ProgressLabel.Bytes(1000L.bytes, 1000L.bytes), render.label)
|
||||
assertEquals(TransferControls.ProgressLabel.Bytes(expectedTotal.bytes, expectedTotal.bytes), render.label)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
Reference in New Issue
Block a user