Add @ChecksSdkIntAtLeast annotation, to be able to remove AndroidVersionTestOverrider

This commit is contained in:
Benoit Marty 2022-09-16 15:22:21 +02:00 committed by Benoit Marty
parent bb2eb56ee6
commit 832a472b57
3 changed files with 13 additions and 58 deletions

View File

@ -1,46 +0,0 @@
/*
* 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
import android.os.Build
import java.lang.reflect.Field
/**
* Used to override [Build.VERSION.SDK_INT]. Ideally an interface should be used instead, but that approach forces us to either add suppress lint annotations
* and potentially miss an API version issue or write a custom lint rule, which seems like an overkill.
*/
object AndroidVersionTestOverrider {
private var initialValue: Int? = null
fun override(newVersion: Int) {
if (initialValue == null) {
initialValue = Build.VERSION.SDK_INT
}
val field = Build.VERSION::class.java.getField("SDK_INT")
setStaticField(field, newVersion)
}
fun restore() {
initialValue?.let { override(it) }
}
private fun setStaticField(field: Field, value: Any) {
field.isAccessible = true
field.set(null, value)
}
}

View File

@ -18,41 +18,36 @@ package im.vector.app.features.voice
import android.os.Build import android.os.Build
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import im.vector.app.AndroidVersionTestOverrider import im.vector.app.TestBuildVersionSdkIntProvider
import im.vector.app.features.DefaultVectorFeatures import im.vector.app.features.DefaultVectorFeatures
import io.mockk.every import io.mockk.every
import io.mockk.spyk import io.mockk.spyk
import org.amshove.kluent.shouldBeInstanceOf import org.amshove.kluent.shouldBeInstanceOf
import org.junit.After
import org.junit.Test import org.junit.Test
class VoiceRecorderProviderTests { class VoiceRecorderProviderTests {
private val context = InstrumentationRegistry.getInstrumentation().targetContext private val context = InstrumentationRegistry.getInstrumentation().targetContext
private val provider = spyk(VoiceRecorderProvider(context, DefaultVectorFeatures())) private val buildVersionSdkIntProvider = TestBuildVersionSdkIntProvider()
private val provider = spyk(VoiceRecorderProvider(context, DefaultVectorFeatures(), buildVersionSdkIntProvider))
@After
fun tearDown() {
AndroidVersionTestOverrider.restore()
}
@Test @Test
fun provideVoiceRecorderOnAndroidQAndCodecReturnsQRecorder() { fun provideVoiceRecorderOnAndroidQAndCodecReturnsQRecorder() {
AndroidVersionTestOverrider.override(Build.VERSION_CODES.Q) buildVersionSdkIntProvider.value = Build.VERSION_CODES.Q
every { provider.hasOpusEncoder() } returns true every { provider.hasOpusEncoder() } returns true
provider.provideVoiceRecorder().shouldBeInstanceOf(VoiceRecorderQ::class) provider.provideVoiceRecorder().shouldBeInstanceOf(VoiceRecorderQ::class)
} }
@Test @Test
fun provideVoiceRecorderOnAndroidQButNoCodecReturnsLRecorder() { fun provideVoiceRecorderOnAndroidQButNoCodecReturnsLRecorder() {
AndroidVersionTestOverrider.override(Build.VERSION_CODES.Q) buildVersionSdkIntProvider.value = Build.VERSION_CODES.Q
every { provider.hasOpusEncoder() } returns false every { provider.hasOpusEncoder() } returns false
provider.provideVoiceRecorder().shouldBeInstanceOf(VoiceRecorderL::class) provider.provideVoiceRecorder().shouldBeInstanceOf(VoiceRecorderL::class)
} }
@Test @Test
fun provideVoiceRecorderOnOlderAndroidVersionReturnsLRecorder() { fun provideVoiceRecorderOnOlderAndroidVersionReturnsLRecorder() {
AndroidVersionTestOverrider.override(Build.VERSION_CODES.LOLLIPOP) buildVersionSdkIntProvider.value = Build.VERSION_CODES.LOLLIPOP
provider.provideVoiceRecorder().shouldBeInstanceOf(VoiceRecorderL::class) provider.provideVoiceRecorder().shouldBeInstanceOf(VoiceRecorderL::class)
} }
} }

View File

@ -20,14 +20,17 @@ import android.content.Context
import android.media.MediaCodecList import android.media.MediaCodecList
import android.media.MediaFormat import android.media.MediaFormat
import android.os.Build import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import im.vector.app.features.VectorFeatures import im.vector.app.features.VectorFeatures
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import org.matrix.android.sdk.api.util.BuildVersionSdkIntProvider
import javax.inject.Inject import javax.inject.Inject
class VoiceRecorderProvider @Inject constructor( class VoiceRecorderProvider @Inject constructor(
private val context: Context, private val context: Context,
private val vectorFeatures: VectorFeatures, private val vectorFeatures: VectorFeatures,
private val buildVersionSdkIntProvider: BuildVersionSdkIntProvider,
) { ) {
fun provideVoiceRecorder(): VoiceRecorder { fun provideVoiceRecorder(): VoiceRecorder {
return if (useFallbackRecorder()) { return if (useFallbackRecorder()) {
@ -37,8 +40,11 @@ class VoiceRecorderProvider @Inject constructor(
} }
} }
@ChecksSdkIntAtLeast(api = 29)
private fun useFallbackRecorder(): Boolean { private fun useFallbackRecorder(): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || !hasOpusEncoder() || vectorFeatures.forceUsageOfOpusEncoder() return buildVersionSdkIntProvider.get() < Build.VERSION_CODES.Q ||
!hasOpusEncoder() ||
vectorFeatures.forceUsageOfOpusEncoder()
} }
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)