diff --git a/dependencies.gradle b/dependencies.gradle index 2e70304670..d4f8ea43e6 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -99,7 +99,7 @@ ext.libs = [ 'flipperNetworkPlugin' : "com.facebook.flipper:flipper-network-plugin:$flipper", ], element : [ - 'opusencoder' : "io.element.android:opusencoder:1.0.4", + 'opusencoder' : "io.element.android:opusencoder:1.1.0", ], squareup : [ 'moshi' : "com.squareup.moshi:moshi:$moshi", diff --git a/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderLTests.kt b/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderLTests.kt index 3d7ac3971c..374396f60b 100644 --- a/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderLTests.kt +++ b/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderLTests.kt @@ -19,7 +19,6 @@ package im.vector.app.features.voice import android.Manifest import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.GrantPermissionRule -import io.mockk.spyk import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import org.amshove.kluent.shouldBeNull @@ -38,7 +37,7 @@ class VoiceRecorderLTests { val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(Manifest.permission.RECORD_AUDIO) private val context = InstrumentationRegistry.getInstrumentation().targetContext - private val recorder = spyk(VoiceRecorderL(context, Dispatchers.IO)) + private val recorder = VoiceRecorderL(context, Dispatchers.IO, createFakeOpusEncoder()) @Test fun startRecordCreatesOggFile() = with(recorder) { diff --git a/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTestExt.kt b/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTestExt.kt index 4275ae89b3..75303556b2 100644 --- a/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTestExt.kt +++ b/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTestExt.kt @@ -17,6 +17,7 @@ package im.vector.app.features.voice import im.vector.app.core.utils.waitUntil +import im.vector.app.test.fakes.FakeOggOpusEncoder import org.amshove.kluent.shouldExist import org.amshove.kluent.shouldNotBeNull import java.io.File @@ -34,3 +35,5 @@ suspend fun VoiceRecorder.waitUntilRecordingFileExists(timeout: Duration = 1.sec } return getVoiceMessageFile() } + +internal fun createFakeOpusEncoder() = FakeOggOpusEncoder().apply { createEmptyFileOnInit() } diff --git a/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTests.kt b/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTests.kt index 7feeff83cb..72d959f3dd 100644 --- a/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTests.kt +++ b/vector/src/androidTest/java/im/vector/app/features/voice/VoiceRecorderTests.kt @@ -29,7 +29,7 @@ import java.io.File class VoiceRecorderTests { private val context = InstrumentationRegistry.getInstrumentation().targetContext - private val voiceRecorder = VoiceRecorderL(context, Dispatchers.IO) + private val voiceRecorder = VoiceRecorderL(context, Dispatchers.IO, createFakeOpusEncoder()) private val audioDirectory = File(context.cacheDir, "voice_records") @After diff --git a/vector/src/androidTest/java/im/vector/app/test/fakes/FakeOggOpusEncoder.kt b/vector/src/androidTest/java/im/vector/app/test/fakes/FakeOggOpusEncoder.kt new file mode 100644 index 0000000000..a13c8dbb78 --- /dev/null +++ b/vector/src/androidTest/java/im/vector/app/test/fakes/FakeOggOpusEncoder.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fakes + +import io.element.android.opusencoder.OggOpusEncoder +import io.mockk.every +import io.mockk.mockk +import java.io.File + +class FakeOggOpusEncoder : OggOpusEncoder by mockk() { + + init { + every { init(any(), any()) } returns 0 + every { setBitrate(any()) } returns 0 + every { encode(any(), any()) } returns 0 + every { release() } answers {} + } + + fun createEmptyFileOnInit() { + every { init(any(), any()) } answers { + val filePath = arg(0) + if (File(filePath).createNewFile()) 0 else 1 + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt index c8eeb45635..d5395cc849 100644 --- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt +++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderL.kt @@ -42,6 +42,7 @@ import kotlin.coroutines.CoroutineContext class VoiceRecorderL( context: Context, coroutineContext: CoroutineContext, + private val codec: OggOpusEncoder, ) : VoiceRecorder { companion object { @@ -58,7 +59,6 @@ class VoiceRecorderL( private var audioRecorder: AudioRecord? = null private var noiseSuppressor: NoiseSuppressor? = null private var automaticGainControl: AutomaticGainControl? = null - private val codec = OggOpusEncoder() // Size of the audio buffer for Short values private var bufferSizeInShorts = 0 diff --git a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt index 05e537b2b0..38771be44e 100644 --- a/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt +++ b/vector/src/main/java/im/vector/app/features/voice/VoiceRecorderProvider.kt @@ -23,6 +23,7 @@ import android.os.Build import androidx.annotation.ChecksSdkIntAtLeast import androidx.annotation.VisibleForTesting import im.vector.app.features.VectorFeatures +import io.element.android.opusencoder.OggOpusEncoder import kotlinx.coroutines.Dispatchers import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider import javax.inject.Inject @@ -36,7 +37,7 @@ class VoiceRecorderProvider @Inject constructor( return if (useNativeRecorder()) { VoiceRecorderQ(context) } else { - VoiceRecorderL(context, Dispatchers.IO) + VoiceRecorderL(context, Dispatchers.IO, OggOpusEncoder.create()) } }