Skip to content

Commit

Permalink
fix: add audio asset metadata (WPB-3334) (#1970)
Browse files Browse the repository at this point in the history
* fix: add audio asset metadata (WPB-3334) (#1969)

* fix: add audio/mp4 as audio mime type

* fix: get audio length in ms from audio asset as audio/mp4 mime type

* fix: map audio metadata to protobuf

* fix: add tests

* fix: add missing param in testservice

* trigger build

---------

Co-authored-by: Alexandre Ferris <ferris.alexandre@gmail.com>
  • Loading branch information
github-actions[bot] and alexandreferris authored Aug 9, 2023
1 parent 9692232 commit 36b2c20
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fun isDisplayableImageMimeType(mimeType: String): Boolean = mimeType in setOf(
)

fun isAudioMimeType(mimeType: String): Boolean = mimeType in setOf(
"audio/mp3", "audio/mpeg", "audio/ogg", "audio/wav", "audio/x-wav", "audio/x-pn-wav"
"audio/mp3", "audio/mp4", "audio/mpeg", "audio/ogg", "audio/wav", "audio/x-wav", "audio/x-pn-wav"
)

fun isVideoMimeType(mimeType: String): Boolean = mimeType in setOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ class AssetMapperImpl(
)
)

is Audio -> Asset.Original.MetaData.Audio(
audio = Asset.AudioMetaData(
durationInMillis = metadata.durationMs,
normalizedLoudness = metadata.normalizedLoudness?.let { ByteArr(it) }
)
)

else -> null
}
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.wire.kalium.cryptography.utils.generateRandomAES256Key
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.data.asset.AssetRepository
import com.wire.kalium.logic.data.asset.UploadedAssetId
import com.wire.kalium.logic.data.asset.isAudioMimeType
import com.wire.kalium.logic.data.asset.isDisplayableImageMimeType
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.message.AssetContent
Expand Down Expand Up @@ -85,7 +86,8 @@ interface ScheduleNewAssetMessageUseCase {
assetName: String,
assetMimeType: String,
assetWidth: Int?,
assetHeight: Int?
assetHeight: Int?,
audioLengthInMs: Long
): ScheduleNewAssetMessageResult
}

Expand Down Expand Up @@ -118,6 +120,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl(
assetMimeType: String,
assetWidth: Int?,
assetHeight: Int?,
audioLengthInMs: Long
): ScheduleNewAssetMessageResult {
slowSyncRepository.slowSyncStatus.first {
it is SlowSyncStatus.Complete
Expand All @@ -142,6 +145,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl(
assetWidth = assetWidth,
assetHeight = assetHeight,
expireAfter = messageTimer,
audioLengthInMs = audioLengthInMs,
expectsReadConfirmation = expectsReadConfirmation
).onSuccess { (currentAssetMessageContent, message) ->
// We schedule the asset upload and return Either.Right so later it's transformed to Success(message.id)
Expand Down Expand Up @@ -186,6 +190,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl(
assetWidth: Int?,
assetHeight: Int?,
expireAfter: Duration?,
audioLengthInMs: Long,
expectsReadConfirmation: Boolean
): Either<CoreFailure, Pair<AssetMessageMetadata, Message.Regular>> = currentClientIdProvider().flatMap { currentClientId ->
// Create a temporary asset key and domain
Expand All @@ -208,6 +213,7 @@ internal class ScheduleNewAssetMessageUseCaseImpl(
sha256Key = SHA256Key(byteArrayOf()),
// Asset ID will be replaced with right value after asset upload
assetId = UploadedAssetId(generatedAssetUuid, tempAssetDomain),
audioLengthInMs = audioLengthInMs
)

val message = Message.Regular(
Expand Down Expand Up @@ -307,6 +313,13 @@ internal class ScheduleNewAssetMessageUseCaseImpl(
AssetContent.AssetMetadata.Image(assetWidth, assetHeight)
}

isAudioMimeType(mimeType) -> {
AssetContent.AssetMetadata.Audio(
durationMs = audioLengthInMs,
normalizedLoudness = null
)
}

else -> null
},
remoteData = AssetContent.RemoteData(
Expand Down Expand Up @@ -345,5 +358,6 @@ private data class AssetMessageMetadata(
val assetWidth: Int?,
val assetHeight: Int?,
val otrKey: AES256Key,
val sha256Key: SHA256Key
val sha256Key: SHA256Key,
val audioLengthInMs: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.logic.data.asset

import com.wire.kalium.logic.data.message.AssetContent
import com.wire.kalium.logic.data.message.EncryptionAlgorithmMapper
import com.wire.kalium.logic.data.message.Message
import com.wire.kalium.logic.data.message.MessageContent
import com.wire.kalium.logic.data.message.MessageEncryptionAlgorithm
import com.wire.kalium.protobuf.messages.Asset
import com.wire.kalium.util.KaliumDispatcher
import io.mockative.Mock
import io.mockative.classOf
import io.mockative.mock
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull

class AssetMapperTest {

@Test
fun givenAudioAssetContent_whenMappingToProtoAssetMessage_thenReturnCorrectProtoAudioMetadata() = runTest {
// given
val audioMetadata = AssetContent.AssetMetadata.Audio(
durationMs = 4444,
normalizedLoudness = null
)
val messageContent = MessageContent.Asset(
value = AssetContent(
sizeInBytes = 10000,
name = "audio.m4a",
mimeType = "audio/mp4",
metadata = audioMetadata,
remoteData = AssetContent.RemoteData(
otrKey = byteArrayOf(),
sha256 = byteArrayOf(),
assetId = "abcd-1234",
assetToken = "token",
assetDomain = "domain",
encryptionAlgorithm = MessageEncryptionAlgorithm.AES_GCM
),
uploadStatus = Message.UploadStatus.FAILED_UPLOAD,
downloadStatus = Message.DownloadStatus.NOT_DOWNLOADED
)
)
val (_, mapper) = Arrangement()
.arrange()

// when
val result = mapper.fromAssetContentToProtoAssetMessage(
messageContent = messageContent,
expectsReadConfirmation = true
)

// then
assertEquals(
audioMetadata.durationMs,
(result.original?.metaData as Asset.Original.MetaData.Audio).value.durationInMillis
)
assertNull(
(result.original?.metaData as Asset.Original.MetaData.Audio).value.normalizedLoudness
)
}

private class Arrangement {

@Mock
val dispatcher = mock(classOf<KaliumDispatcher>())

val mapper = AssetMapperImpl(
encryptionAlgorithmMapper = EncryptionAlgorithmMapper(),
dispatcher = dispatcher
)

fun arrange() = this to mapper
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -134,7 +135,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -166,7 +168,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -205,7 +208,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)

advanceUntilIdle()
Expand Down Expand Up @@ -250,7 +254,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -289,7 +294,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -336,7 +342,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -390,7 +397,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -434,7 +442,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down Expand Up @@ -476,7 +485,8 @@ class ScheduleNewAssetMessageUseCaseTest {
assetName = assetName,
assetMimeType = "text/plain",
assetWidth = null,
assetHeight = null
assetHeight = null,
audioLengthInMs = 0
)
advanceUntilIdle()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ sealed class ConversationRepository {
type,
null,
null,
0L
)
}
when (sendResult) {
Expand Down Expand Up @@ -406,6 +407,7 @@ sealed class ConversationRepository {
"image", type,
width,
height,
0L
)
if (sendResult is ScheduleNewAssetMessageResult.Failure) {
if (sendResult.coreFailure is StorageFailure.Generic) {
Expand Down

0 comments on commit 36b2c20

Please sign in to comment.