Skip to content

Commit

Permalink
fix: Audio Message not being send with correct mimeType (WPB-3534) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandreferris committed Aug 1, 2023
1 parent 8bbd3f9 commit 12fd721
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.datetime.Instant
import okio.Path
import okio.Path.Companion.toPath
import javax.inject.Inject
import com.wire.kalium.logic.data.id.QualifiedID as ConversationId

Expand Down Expand Up @@ -237,7 +239,16 @@ class MessageComposerViewModel @Inject constructor(
}

is ComposableMessageBundle.AttachmentPickedBundle -> {
handleAttachment(messageBundle)
handleAssetMessageBundle(
attachmentUri = messageBundle.attachmentUri
)
}

is ComposableMessageBundle.AudioMessageBundle -> {
handleAssetMessageBundle(
attachmentUri = messageBundle.attachmentUri,
audioPath = messageBundle.attachmentUri.uri.path?.toPath()
)
}

is ComposableMessageBundle.SendTextMessageBundle -> {
Expand All @@ -259,21 +270,24 @@ class MessageComposerViewModel @Inject constructor(
}
}

private suspend fun handleAttachment(
messageBundle: ComposableMessageBundle.AttachmentPickedBundle
private suspend fun handleAssetMessageBundle(
attachmentUri: UriAsset,
audioPath: Path? = null
) {
with(messageBundle) {
val tempCachePath = kaliumFileSystem.rootCachePath
val assetBundle = fileManager.getAssetBundleFromUri(attachmentUri.uri, tempCachePath)
if (assetBundle != null) {
// The max limit for sending assets changes between user and asset types.
// Check [GetAssetSizeLimitUseCase] class for more detailed information about the real limits.
val maxSizeLimitInBytes =
getAssetSizeLimit(isImage = assetBundle.assetType == AttachmentType.IMAGE)
handleBundle(assetBundle, maxSizeLimitInBytes, messageBundle.attachmentUri)
} else {
onSnackbarMessage(ConversationSnackbarMessages.ErrorPickingAttachment)
}
val tempCachePath = kaliumFileSystem.rootCachePath
val assetBundle = fileManager.getAssetBundleFromUri(
attachmentUri = attachmentUri.uri,
tempCachePath = tempCachePath,
audioPath = audioPath
)
if (assetBundle != null) {
// The max limit for sending assets changes between user and asset types.
// Check [GetAssetSizeLimitUseCase] class for more detailed information about the real limits.
val maxSizeLimitInBytes =
getAssetSizeLimit(isImage = assetBundle.assetType == AttachmentType.IMAGE)
handleBundle(assetBundle, maxSizeLimitInBytes, attachmentUri)
} else {
onSnackbarMessage(ConversationSnackbarMessages.ErrorPickingAttachment)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import com.wire.android.ui.home.conversations.MessageComposerViewState
import com.wire.android.ui.home.conversations.model.UriAsset
import com.wire.android.ui.home.messagecomposer.state.AdditionalOptionStateHolder
import com.wire.android.ui.home.messagecomposer.state.AdditionalOptionSubMenuState
import com.wire.android.ui.home.messagecomposer.state.ComposableMessageBundle.AudioMessageBundle
import com.wire.android.ui.home.messagecomposer.state.ComposableMessageBundle.AttachmentPickedBundle
import com.wire.android.ui.home.messagecomposer.state.MessageBundle
import com.wire.android.ui.home.messagecomposer.state.MessageComposerStateHolder
Expand Down Expand Up @@ -151,9 +152,7 @@ fun MessageComposer(
},
onPingOptionClicked = { onSendMessageBundle(Ping) },
onAttachmentPicked = { onSendMessageBundle(AttachmentPickedBundle(it)) },
onAudioRecorded = {
onSendMessageBundle(AttachmentPickedBundle(it))
},
onAudioRecorded = { onSendMessageBundle(AudioMessageBundle(it)) },
onChangeSelfDeletionClicked = onChangeSelfDeletionClicked,
onSearchMentionQueryChanged = onSearchMentionQueryChanged,
onClearMentionSearchResult = onClearMentionSearchResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ class AudioMediaRecorder @Inject constructor(
.toFile()

mediaRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
mediaRecorder?.setAudioSamplingRate(SAMPLING_RATE)
mediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
mediaRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
mediaRecorder?.setOutputFile(outputFile)
mediaRecorder?.setAudioChannels(AUDIO_CHANNELS)
mediaRecorder?.setAudioEncodingBitRate(AUDIO_ENCONDING_BIT_RATE)
mediaRecorder?.setMaxFileSize(assetLimitInMegabyte)
mediaRecorder?.setOutputFile(outputFile)

observeAudioFileSize()
}
Expand Down Expand Up @@ -127,5 +130,8 @@ class AudioMediaRecorder @Inject constructor(
fun getRecordingAudioFileName(): String =
"wire-audio-${DateTimeUtil.currentInstant().audioFileDateTime()}.m4a"
const val SIZE_OF_1MB = 1024 * 1024
const val AUDIO_CHANNELS = 1
const val SAMPLING_RATE = 44100
const val AUDIO_ENCONDING_BIT_RATE = 96000
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ sealed class ComposableMessageBundle : MessageBundle {
data class AttachmentPickedBundle(
val attachmentUri: UriAsset
) : ComposableMessageBundle()

data class AudioMessageBundle(
val attachmentUri: UriAsset
) : ComposableMessageBundle()
}

object Ping : MessageBundle
Expand Down
11 changes: 8 additions & 3 deletions app/src/main/kotlin/com/wire/android/util/FileManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,17 @@ class FileManager @Inject constructor(@ApplicationContext private val context: C
suspend fun getAssetBundleFromUri(
attachmentUri: Uri,
tempCachePath: Path,
audioPath: Path? = null,
dispatcher: DispatcherProvider = DefaultDispatcherProvider(),
): AssetBundle? = withContext(dispatcher.io()) {
try {
val assetFileName = context.getFileName(attachmentUri) ?: throw IOException("The selected asset has an invalid name")
val assetFileName = context.getFileName(attachmentUri)
?: throw IOException("The selected asset has an invalid name")
val fullTempAssetPath = "$tempCachePath/${UUID.randomUUID()}".toPath()
val mimeType = attachmentUri.getMimeType(context).orDefault(DEFAULT_FILE_MIME_TYPE)
val assetPath = audioPath ?: fullTempAssetPath
val mimeType = if (audioPath != null) AUDIO_MIME_TYPE else attachmentUri
.getMimeType(context)
.orDefault(DEFAULT_FILE_MIME_TYPE)
val attachmentType = AttachmentType.fromMimeTypeString(mimeType)
val assetSize = if (attachmentType == AttachmentType.IMAGE) {
attachmentUri.resampleImageAndCopyToTempPath(context, fullTempAssetPath)
Expand All @@ -123,7 +128,7 @@ class FileManager @Inject constructor(@ApplicationContext private val context: C
// of video assets hitting the max limit.
copyToPath(attachmentUri, fullTempAssetPath)
}
AssetBundle(mimeType, fullTempAssetPath, assetSize, assetFileName, attachmentType)
AssetBundle(mimeType, assetPath, assetSize, assetFileName, attachmentType)
} catch (e: IOException) {
appLogger.e("There was an error while obtaining the file from disk", e)
null
Expand Down
1 change: 1 addition & 0 deletions app/src/main/kotlin/com/wire/android/util/FileUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,4 @@ fun findFirstUniqueName(dir: File, desiredName: String): String {
private const val ATTACHMENT_FILENAME = "attachment"
private const val DATA_COPY_BUFFER_SIZE = 2048
const val SDK_VERSION = 33
const val AUDIO_MIME_TYPE = "audio/mp4"
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ internal class MessageComposerViewModelArrangement {
}

fun withGetAssetBundleFromUri(assetBundle: AssetBundle?) = apply {
coEvery { fileManager.getAssetBundleFromUri(any(), any(), any()) } returns assetBundle
coEvery { fileManager.getAssetBundleFromUri(any(), any(), any(), any()) } returns assetBundle
}

fun withSaveToExternalMediaStorage(resultFileName: String?) = apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,4 +525,40 @@ class MessageComposerViewModelTest {
assertInstanceOf(SelfDeletionTimer.Enabled::class.java, viewModel.messageComposerViewState.value.selfDeletionTimer)
assertEquals(expectedDuration, viewModel.messageComposerViewState.value.selfDeletionTimer.duration)
}

@Test
fun `given the user sends an audio message, when invoked, then sendAssetMessageUseCase gets called`() =
runTest {
// Given
val limit = ASSET_SIZE_DEFAULT_LIMIT_BYTES
val assetPath = "mocked-asset-data-path".toPath()
val assetContent = "some-dummy-audio".toByteArray()
val assetName = "mocked_audio.m4a"
val assetSize = 1L
val (arrangement, viewModel) = MessageComposerViewModelArrangement()
.withSuccessfulViewModelInit()
.withStoredAsset(assetPath, assetContent)
.withSuccessfulSendAttachmentMessage()
.withGetAssetSizeLimitUseCase(false, limit)
.arrange()
val mockedAttachment = AssetBundle(
"audio/mp4", assetPath, assetSize, assetName, AttachmentType.AUDIO
)

// When
viewModel.sendAttachment(mockedAttachment)

// Then
coVerify(exactly = 1) {
arrangement.sendAssetMessage.invoke(
any(),
any(),
any(),
any(),
any(),
any(),
any()
)
}
}
}

0 comments on commit 12fd721

Please sign in to comment.