Use MimeTypes object instead of hard-coded strings.

This commit is contained in:
Benoit Marty 2023-11-27 21:55:39 +01:00 committed by Benoit Marty
parent 04be1f0385
commit 4f32299280
14 changed files with 37 additions and 24 deletions

View file

@ -16,6 +16,7 @@
package io.element.android.features.messages.impl.voicemessages.composer package io.element.android.features.messages.impl.voicemessages.composer
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.mediaplayer.api.MediaPlayer import io.element.android.libraries.mediaplayer.api.MediaPlayer
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@ -41,7 +42,7 @@ class VoiceMessageComposerPlayer @Inject constructor(
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
) { ) {
companion object { companion object {
const val MIME_TYPE = "audio/ogg" const val MIME_TYPE = MimeTypes.Ogg
} }
private var mediaPath: String? = null private var mediaPath: String? = null

View file

@ -17,6 +17,7 @@
package io.element.android.features.messages.impl.voicemessages.timeline package io.element.android.features.messages.impl.voicemessages.timeline
import com.squareup.anvil.annotations.ContributesBinding import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.MediaSource
@ -196,7 +197,7 @@ class DefaultVoiceMessagePlayer(
mediaPlayer.setMedia( mediaPlayer.setMedia(
uri = mediaFile.path, uri = mediaFile.path,
mediaId = eventId.value, mediaId = eventId.value,
mimeType = "audio/ogg", // Files in the voice cache have no extension so we need to set the mime type manually. mimeType = MimeTypes.Ogg, // Files in the voice cache have no extension so we need to set the mime type manually.
startPositionMs = if (state.isEnded) 0L else state.currentPosition, startPositionMs = if (state.isEnded) 0L else state.currentPosition,
) )
} }

View file

@ -147,7 +147,7 @@ class TimelineItemContentMessageFactoryTest {
blurHash = null, blurHash = null,
height = null, height = null,
width = null, width = null,
mimeType = "application/octet-stream", mimeType = MimeTypes.OctetStream,
formattedFileSize = "0 Bytes", formattedFileSize = "0 Bytes",
fileExtension = "", fileExtension = "",
) )
@ -210,7 +210,7 @@ class TimelineItemContentMessageFactoryTest {
body = "body", body = "body",
duration = Duration.ZERO, duration = Duration.ZERO,
mediaSource = MediaSource(url = "url", json = null), mediaSource = MediaSource(url = "url", json = null),
mimeType = "application/octet-stream", mimeType = MimeTypes.OctetStream,
formattedFileSize = "0 Bytes", formattedFileSize = "0 Bytes",
fileExtension = "", fileExtension = "",
) )
@ -259,7 +259,7 @@ class TimelineItemContentMessageFactoryTest {
body = "body", body = "body",
duration = Duration.ZERO, duration = Duration.ZERO,
mediaSource = MediaSource(url = "url", json = null), mediaSource = MediaSource(url = "url", json = null),
mimeType = "application/octet-stream", mimeType = MimeTypes.OctetStream,
waveform = emptyList<Float>().toImmutableList() waveform = emptyList<Float>().toImmutableList()
) )
assertThat(result).isEqualTo(expected) assertThat(result).isEqualTo(expected)
@ -316,7 +316,7 @@ class TimelineItemContentMessageFactoryTest {
body = "body", body = "body",
duration = Duration.ZERO, duration = Duration.ZERO,
mediaSource = MediaSource(url = "url", json = null), mediaSource = MediaSource(url = "url", json = null),
mimeType = "application/octet-stream", mimeType = MimeTypes.OctetStream,
formattedFileSize = "0 Bytes", formattedFileSize = "0 Bytes",
fileExtension = "" fileExtension = ""
) )
@ -337,7 +337,7 @@ class TimelineItemContentMessageFactoryTest {
thumbnailSource = null, thumbnailSource = null,
formattedFileSize = "0 Bytes", formattedFileSize = "0 Bytes",
fileExtension = "", fileExtension = "",
mimeType = "application/octet-stream", mimeType = MimeTypes.OctetStream,
blurhash = null, blurhash = null,
width = null, width = null,
height = null, height = null,
@ -402,7 +402,7 @@ class TimelineItemContentMessageFactoryTest {
thumbnailSource = null, thumbnailSource = null,
formattedFileSize = "0 Bytes", formattedFileSize = "0 Bytes",
fileExtension = "", fileExtension = "",
mimeType = "application/octet-stream" mimeType = MimeTypes.OctetStream
) )
assertThat(result).isEqualTo(expected) assertThat(result).isEqualTo(expected)
} }

View file

@ -17,6 +17,7 @@
package io.element.android.features.messages.impl.voicemessages.timeline package io.element.android.features.messages.impl.voicemessages.timeline
import com.google.common.truth.Truth import com.google.common.truth.Truth
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.test.media.FakeMediaLoader import io.element.android.libraries.matrix.test.media.FakeMediaLoader
@ -143,7 +144,7 @@ private fun createDefaultVoiceMessageMediaRepo(
url = mxcUri, url = mxcUri,
json = null json = null
), ),
mimeType = "audio/ogg", mimeType = MimeTypes.Ogg,
body = "someBody.ogg" body = "someBody.ogg"
) )

View file

@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.voicemessages.timeline
import app.cash.turbine.TurbineTestContext import app.cash.turbine.TurbineTestContext
import app.cash.turbine.test import app.cash.turbine.test
import com.google.common.truth.Truth import com.google.common.truth.Truth
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.AN_EVENT_ID
@ -287,7 +288,7 @@ private fun createDefaultVoiceMessagePlayer(
url = MXC_URI, url = MXC_URI,
json = null json = null
), ),
mimeType = "audio/ogg", mimeType = MimeTypes.Ogg,
body = "someBody.ogg" body = "someBody.ogg"
) )

View file

@ -17,6 +17,7 @@
package io.element.android.features.messages.impl.voicemessages.timeline package io.element.android.features.messages.impl.voicemessages.timeline
import com.google.common.truth.Truth import com.google.common.truth.Truth
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
@ -37,7 +38,7 @@ class RedactedVoiceMessageManagerTest {
@Test @Test
fun `redacted event - no playing related media`() = runTest { fun `redacted event - no playing related media`() = runTest {
val mediaPlayer = FakeMediaPlayer().apply { val mediaPlayer = FakeMediaPlayer().apply {
setMedia(uri = "someUri", mediaId = AN_EVENT_ID.value, mimeType = "audio/ogg") setMedia(uri = "someUri", mediaId = AN_EVENT_ID.value, mimeType = MimeTypes.Ogg)
play() play()
} }
val manager = aDefaultRedactedVoiceMessageManager(mediaPlayer = mediaPlayer) val manager = aDefaultRedactedVoiceMessageManager(mediaPlayer = mediaPlayer)
@ -54,7 +55,7 @@ class RedactedVoiceMessageManagerTest {
@Test @Test
fun `redacted event - playing related media is paused`() = runTest { fun `redacted event - playing related media is paused`() = runTest {
val mediaPlayer = FakeMediaPlayer().apply { val mediaPlayer = FakeMediaPlayer().apply {
setMedia(uri = "someUri", mediaId = AN_EVENT_ID.value, mimeType = "audio/ogg") setMedia(uri = "someUri", mediaId = AN_EVENT_ID.value, mimeType = MimeTypes.Ogg)
play() play()
} }
val manager = aDefaultRedactedVoiceMessageManager(mediaPlayer = mediaPlayer) val manager = aDefaultRedactedVoiceMessageManager(mediaPlayer = mediaPlayer)

View file

@ -29,6 +29,7 @@ import androidx.annotation.ChecksSdkIntAtLeast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import io.element.android.libraries.androidutils.R import io.element.android.libraries.androidutils.R
import io.element.android.libraries.androidutils.compat.getApplicationInfoCompat import io.element.android.libraries.androidutils.compat.getApplicationInfoCompat
import io.element.android.libraries.core.mimetype.MimeTypes
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O) @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.O)
fun supportNotificationChannels() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O fun supportNotificationChannels() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
@ -125,7 +126,7 @@ fun Context.startSharePlainTextIntent(
noActivityFoundMessage: String = getString(R.string.error_no_compatible_app_found), noActivityFoundMessage: String = getString(R.string.error_no_compatible_app_found),
) { ) {
val share = Intent(Intent.ACTION_SEND) val share = Intent(Intent.ACTION_SEND)
share.type = "text/plain" share.type = MimeTypes.PlainText
share.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT) share.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
// Add data to the intent, the receiving app will decide what to do with it. // Add data to the intent, the receiving app will decide what to do with it.
share.putExtra(Intent.EXTRA_SUBJECT, subject) share.putExtra(Intent.EXTRA_SUBJECT, subject)

View file

@ -18,6 +18,7 @@ package io.element.android.libraries.mediaupload.api
import android.net.Uri import android.net.Uri
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor import io.element.android.libraries.mediaupload.test.FakeMediaPreProcessor
@ -39,7 +40,7 @@ class MediaSenderTests {
val sender = aMediaSender(preProcessor) val sender = aMediaSender(preProcessor)
val uri = Uri.parse("content://image.jpg") val uri = Uri.parse("content://image.jpg")
sender.sendMedia(uri = uri, mimeType = "image/jpeg", compressIfPossible = true) sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
assertThat(preProcessor.processCallCount).isEqualTo(1) assertThat(preProcessor.processCallCount).isEqualTo(1)
} }
@ -50,7 +51,7 @@ class MediaSenderTests {
val sender = aMediaSender(room = room) val sender = aMediaSender(room = room)
val uri = Uri.parse("content://image.jpg") val uri = Uri.parse("content://image.jpg")
sender.sendMedia(uri = uri, mimeType = "image/jpeg", compressIfPossible = true) sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
assertThat(room.sendMediaCount).isEqualTo(1) assertThat(room.sendMediaCount).isEqualTo(1)
} }
@ -63,7 +64,7 @@ class MediaSenderTests {
val sender = aMediaSender(preProcessor) val sender = aMediaSender(preProcessor)
val uri = Uri.parse("content://image.jpg") val uri = Uri.parse("content://image.jpg")
val result = sender.sendMedia(uri = uri, mimeType = "image/jpeg", compressIfPossible = true) val result = sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
assertThat(result.exceptionOrNull()).isNotNull() assertThat(result.exceptionOrNull()).isNotNull()
} }
@ -76,7 +77,7 @@ class MediaSenderTests {
val sender = aMediaSender(room = room) val sender = aMediaSender(room = room)
val uri = Uri.parse("content://image.jpg") val uri = Uri.parse("content://image.jpg")
val result = sender.sendMedia(uri = uri, mimeType = "image/jpeg", compressIfPossible = true) val result = sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
assertThat(result.exceptionOrNull()).isNotNull() assertThat(result.exceptionOrNull()).isNotNull()
} }
@ -88,7 +89,7 @@ class MediaSenderTests {
val sender = aMediaSender(room = room) val sender = aMediaSender(room = room)
val sendJob = launch { val sendJob = launch {
val uri = Uri.parse("content://image.jpg") val uri = Uri.parse("content://image.jpg")
sender.sendMedia(uri = uri, mimeType = "image/jpeg", compressIfPossible = true) sender.sendMedia(uri = uri, mimeType = MimeTypes.Jpeg, compressIfPossible = true)
} }
// Wait until several internal tasks run and the file is being uploaded // Wait until several internal tasks run and the file is being uploaded
advanceTimeBy(3L) advanceTimeBy(3L)

View file

@ -24,5 +24,6 @@ android {
dependencies { dependencies {
api(projects.libraries.mediaupload.api) api(projects.libraries.mediaupload.api)
implementation(projects.libraries.core)
implementation(projects.tests.testutils) implementation(projects.tests.testutils)
} }

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.mediaupload.test package io.element.android.libraries.mediaupload.test
import android.net.Uri import android.net.Uri
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.media.AudioInfo import io.element.android.libraries.matrix.api.media.AudioInfo
import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.mediaupload.api.MediaPreProcessor import io.element.android.libraries.mediaupload.api.MediaPreProcessor
@ -34,7 +35,7 @@ class FakeMediaPreProcessor : MediaPreProcessor {
MediaUploadInfo.AnyFile( MediaUploadInfo.AnyFile(
File("test"), File("test"),
FileInfo( FileInfo(
mimetype = "*/*", mimetype = MimeTypes.Any,
size = 999L, size = 999L,
thumbnailInfo = null, thumbnailInfo = null,
thumbnailSource = null, thumbnailSource = null,
@ -64,7 +65,7 @@ class FakeMediaPreProcessor : MediaPreProcessor {
audioInfo = AudioInfo( audioInfo = AudioInfo(
duration = 1000.seconds, duration = 1000.seconds,
size = 1000, size = 1000,
mimetype = "audio/ogg", mimetype = MimeTypes.Ogg,
), ),
) )
) )

View file

@ -21,6 +21,7 @@ import android.media.MediaRecorder
import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.ContributesTo
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.voicerecorder.impl.audio.AudioConfig import io.element.android.libraries.voicerecorder.impl.audio.AudioConfig
import io.element.android.libraries.voicerecorder.impl.audio.SampleRate import io.element.android.libraries.voicerecorder.impl.audio.SampleRate
@ -50,7 +51,7 @@ object VoiceRecorderModule {
VoiceFileConfig( VoiceFileConfig(
cacheSubdir = "voice_recordings", cacheSubdir = "voice_recordings",
fileExt = "ogg", fileExt = "ogg",
mimeType = "audio/ogg", mimeType = MimeTypes.Ogg,
) )
@Provides @Provides

View file

@ -21,6 +21,7 @@ import android.media.MediaRecorder
import app.cash.turbine.test import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.appconfig.VoiceMessageConfig import io.element.android.appconfig.VoiceMessageConfig
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.voicerecorder.api.VoiceRecorderState import io.element.android.libraries.voicerecorder.api.VoiceRecorderState
import io.element.android.libraries.voicerecorder.impl.audio.Audio import io.element.android.libraries.voicerecorder.impl.audio.Audio
import io.element.android.libraries.voicerecorder.impl.audio.AudioConfig import io.element.android.libraries.voicerecorder.impl.audio.AudioConfig
@ -85,7 +86,7 @@ class VoiceRecorderImplTest {
assertThat(awaitItem()).isEqualTo( assertThat(awaitItem()).isEqualTo(
VoiceRecorderState.Finished( VoiceRecorderState.Finished(
file = File(FILE_PATH), file = File(FILE_PATH),
mimeType = "audio/ogg", mimeType = MimeTypes.Ogg,
waveform = List(100) { 1f }, waveform = List(100) { 1f },
duration = VoiceMessageConfig.maxVoiceMessageDuration, duration = VoiceMessageConfig.maxVoiceMessageDuration,
) )
@ -107,7 +108,7 @@ class VoiceRecorderImplTest {
assertThat(awaitItem()).isEqualTo( assertThat(awaitItem()).isEqualTo(
VoiceRecorderState.Finished( VoiceRecorderState.Finished(
file = File(FILE_PATH), file = File(FILE_PATH),
mimeType = "audio/ogg", mimeType = MimeTypes.Ogg,
waveform = List(100) { 1f }, waveform = List(100) { 1f },
duration = 5.seconds, duration = 5.seconds,
) )

View file

@ -28,4 +28,5 @@ dependencies {
implementation(libs.coroutines.test) implementation(libs.coroutines.test)
implementation(libs.test.truth) implementation(libs.test.truth)
implementation(projects.libraries.core)
} }

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.voicerecorder.test package io.element.android.libraries.voicerecorder.test
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.voicerecorder.api.VoiceRecorder import io.element.android.libraries.voicerecorder.api.VoiceRecorder
import io.element.android.libraries.voicerecorder.api.VoiceRecorderState import io.element.android.libraries.voicerecorder.api.VoiceRecorderState
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -73,7 +74,7 @@ class FakeVoiceRecorder(
null -> VoiceRecorderState.Idle null -> VoiceRecorderState.Idle
else -> VoiceRecorderState.Finished( else -> VoiceRecorderState.Finished(
file = curRecording!!, file = curRecording!!,
mimeType = "audio/ogg", mimeType = MimeTypes.Ogg,
duration = recordingDuration, duration = recordingDuration,
waveform = waveform, waveform = waveform,
) )