From eda0a6eda7400f8729ad6d09f115feb34e7e087c Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Mon, 15 Mar 2021 17:43:53 -0400 Subject: [PATCH] refactor voice module to use mapbox navigation consumer generic callback --- libnavui-voice/api/current.txt | 17 ++---- .../ui/voice/api/MapboxSpeechApi.kt | 18 ++++-- .../api/MapboxVoiceInstructionsPlayer.kt | 11 ++-- .../navigation/ui/voice/api/PlayCallback.kt | 3 +- .../navigation/ui/voice/api/SpeechCallback.kt | 19 ------ .../api/VoiceInstructionsPlayerCallback.kt | 2 +- .../navigation/ui/voice/model/SpeechVolume.kt | 15 ++++- .../ui/voice/api/MapboxSpeechApiTest.kt | 28 +++++---- .../api/MapboxVoiceInstructionsPlayerTest.kt | 35 +++++------ .../ui/voice/model/SpeechVolumeTest.kt | 24 ++++++++ .../examples/core/MapboxNavigationActivity.kt | 46 +++++++------- .../examples/core/MapboxVoiceActivity.kt | 61 ++++++++++--------- 12 files changed, 150 insertions(+), 129 deletions(-) delete mode 100644 libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/SpeechCallback.kt create mode 100644 libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/model/SpeechVolumeTest.kt diff --git a/libnavui-voice/api/current.txt b/libnavui-voice/api/current.txt index c7419434043..4ec1308dafa 100644 --- a/libnavui-voice/api/current.txt +++ b/libnavui-voice/api/current.txt @@ -6,26 +6,18 @@ package com.mapbox.navigation.ui.voice.api { ctor public MapboxSpeechApi(android.content.Context context, String accessToken, String language); method public void cancel(); method public void clean(com.mapbox.navigation.ui.voice.model.SpeechAnnouncement announcement); - method public void generate(com.mapbox.api.directions.v5.models.VoiceInstructions voiceInstruction, com.mapbox.navigation.ui.voice.api.SpeechCallback callback); + method public void generate(com.mapbox.api.directions.v5.models.VoiceInstructions voiceInstruction, com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer> consumer); } @UiThread public final class MapboxVoiceInstructionsPlayer { ctor public MapboxVoiceInstructionsPlayer(android.content.Context context, String accessToken, String language, com.mapbox.navigation.ui.voice.options.VoiceInstructionsPlayerOptions options = VoiceInstructionsPlayerOptions.().build()); ctor public MapboxVoiceInstructionsPlayer(android.content.Context context, String accessToken, String language); method public void clear(); - method public void play(com.mapbox.navigation.ui.voice.model.SpeechAnnouncement announcement, com.mapbox.navigation.ui.voice.api.VoiceInstructionsPlayerCallback callback); + method public void play(com.mapbox.navigation.ui.voice.model.SpeechAnnouncement announcement, com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer consumer); method public void shutdown(); method public void volume(com.mapbox.navigation.ui.voice.model.SpeechVolume state); } - public interface SpeechCallback { - method public void onSpeech(com.mapbox.navigation.ui.base.model.Expected state); - } - - public interface VoiceInstructionsPlayerCallback { - method public void onDone(com.mapbox.navigation.ui.voice.model.SpeechAnnouncement announcement); - } - } package com.mapbox.navigation.ui.voice.model { @@ -62,13 +54,16 @@ package com.mapbox.navigation.ui.voice.model { } public final class SpeechVolume { - ctor public SpeechVolume(@FloatRange(from=0.0, to=1.0) float level); + ctor public SpeechVolume(@FloatRange(from=com.mapbox.navigation.ui.voice.model.SpeechVolumeKt.MINIMUM_VOLUME_LEVEL, to=com.mapbox.navigation.ui.voice.model.SpeechVolumeKt.MAXIMUM_VOLUME_LEVEL) float level); method public float component1(); method public com.mapbox.navigation.ui.voice.model.SpeechVolume copy(float level); method public float getLevel(); property public final float level; } + public final class SpeechVolumeKt { + } + } package com.mapbox.navigation.ui.voice.options { diff --git a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApi.kt b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApi.kt index a55cea29d12..1ba60256f00 100644 --- a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApi.kt +++ b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApi.kt @@ -3,6 +3,7 @@ package com.mapbox.navigation.ui.voice.api import android.content.Context import com.mapbox.api.directions.v5.models.VoiceInstructions import com.mapbox.navigation.ui.base.model.Expected +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.voice.VoiceAction import com.mapbox.navigation.ui.voice.VoiceProcessor import com.mapbox.navigation.ui.voice.VoiceResult @@ -44,13 +45,18 @@ class MapboxSpeechApi @JvmOverloads constructor( * voice instruction [SpeechAnnouncement] including the synthesized speech mp3 file * from Mapbox's API Voice. * @param voiceInstruction VoiceInstructions object representing [VoiceInstructions] - * @param callback SpeechCallback + * @param consumer is a [SpeechValue] including the announcement to be played when the + * announcement is ready or a [SpeechError] including the error information and a fallback + * with the raw announcement (without file) that can be played with a text-to-speech engine. * @see [cancel] */ - fun generate(voiceInstruction: VoiceInstructions, callback: SpeechCallback) { + fun generate( + voiceInstruction: VoiceInstructions, + consumer: MapboxNavigationConsumer> + ) { currentVoiceFileJob?.cancel() currentVoiceFileJob = mainJobController.scope.launch { - retrieveVoiceFile(voiceInstruction, callback) + retrieveVoiceFile(voiceInstruction, consumer) } } @@ -73,7 +79,7 @@ class MapboxSpeechApi @JvmOverloads constructor( private suspend fun retrieveVoiceFile( voiceInstruction: VoiceInstructions, - callback: SpeechCallback + consumer: MapboxNavigationConsumer> ) { when (val result = voiceAPI.retrieveVoiceFile(voiceInstruction)) { is VoiceState.VoiceResponse -> { @@ -84,7 +90,7 @@ class MapboxSpeechApi @JvmOverloads constructor( is VoiceState.VoiceFile -> { val announcement = voiceInstruction.announcement() val ssmlAnnouncement = voiceInstruction.ssmlAnnouncement() - callback.onSpeech( + consumer.accept( Expected.Success( SpeechValue( // Can't be null as it's checked in retrieveVoiceFile @@ -100,7 +106,7 @@ class MapboxSpeechApi @JvmOverloads constructor( processVoiceAnnouncement( voiceInstruction ) { available -> - callback.onSpeech( + consumer.accept( Expected.Failure( SpeechError( result.exception, diff --git a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayer.kt b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayer.kt index eac9f2ad9a8..63606cc4fcc 100644 --- a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayer.kt +++ b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayer.kt @@ -3,6 +3,7 @@ package com.mapbox.navigation.ui.voice.api import android.content.Context import android.media.AudioManager import androidx.annotation.UiThread +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.voice.model.SpeechAnnouncement import com.mapbox.navigation.ui.voice.model.SpeechVolume import com.mapbox.navigation.ui.voice.options.VoiceInstructionsPlayerOptions @@ -41,8 +42,8 @@ class MapboxVoiceInstructionsPlayer @JvmOverloads constructor( audioFocusDelegate.abandonFocus() val currentPlayCallback = playCallbackQueue.poll() val currentAnnouncement = currentPlayCallback.announcement - val currentClientCallback = currentPlayCallback.callback - currentClientCallback.onDone(currentAnnouncement) + val currentClientCallback = currentPlayCallback.consumer + currentClientCallback.accept(currentAnnouncement) play() } } @@ -58,13 +59,13 @@ class MapboxVoiceInstructionsPlayer @JvmOverloads constructor( * the given voice instruction will be queued to play after. * @param announcement object including the announcement text * and optionally a synthesized speech mp3. - * @param callback + * @param consumer represents that the speech player is done playing */ fun play( announcement: SpeechAnnouncement, - callback: VoiceInstructionsPlayerCallback + consumer: MapboxNavigationConsumer ) { - playCallbackQueue.add(PlayCallback(announcement, callback)) + playCallbackQueue.add(PlayCallback(announcement, consumer)) if (playCallbackQueue.size == 1) { play() } diff --git a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/PlayCallback.kt b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/PlayCallback.kt index c699976c360..35d4946076b 100644 --- a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/PlayCallback.kt +++ b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/PlayCallback.kt @@ -1,8 +1,9 @@ package com.mapbox.navigation.ui.voice.api +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.voice.model.SpeechAnnouncement internal data class PlayCallback( val announcement: SpeechAnnouncement, - val callback: VoiceInstructionsPlayerCallback + val consumer: MapboxNavigationConsumer ) diff --git a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/SpeechCallback.kt b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/SpeechCallback.kt deleted file mode 100644 index b52b301a61e..00000000000 --- a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/SpeechCallback.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.mapbox.navigation.ui.voice.api - -import com.mapbox.navigation.ui.base.model.Expected -import com.mapbox.navigation.ui.voice.model.SpeechError -import com.mapbox.navigation.ui.voice.model.SpeechValue - -/** - * Interface definition for a callback to be invoked when a voice instruction is retrieved. - */ -interface SpeechCallback { - - /** - * Invoked as a result of [MapboxSpeechApi.generate]. - * @param state is a [SpeechValue] including the announcement to be played when the - * announcement is ready or a [SpeechError] including the error information and a fallback - * with the raw announcement (without file) that can be played with a text-to-speech engine. - */ - fun onSpeech(state: Expected) -} diff --git a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/VoiceInstructionsPlayerCallback.kt b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/VoiceInstructionsPlayerCallback.kt index a94eff7ddb7..f396cacc6fa 100644 --- a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/VoiceInstructionsPlayerCallback.kt +++ b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/api/VoiceInstructionsPlayerCallback.kt @@ -5,7 +5,7 @@ import com.mapbox.navigation.ui.voice.model.SpeechAnnouncement /** * Interface definition for a callback to be invoked when a voice instruction is played. */ -interface VoiceInstructionsPlayerCallback { +internal interface VoiceInstructionsPlayerCallback { /** * Invoked when the speech player is done playing. diff --git a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/model/SpeechVolume.kt b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/model/SpeechVolume.kt index 2b4a04c9172..fcb5e72a986 100644 --- a/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/model/SpeechVolume.kt +++ b/libnavui-voice/src/main/java/com/mapbox/navigation/ui/voice/model/SpeechVolume.kt @@ -2,11 +2,20 @@ package com.mapbox.navigation.ui.voice.model import androidx.annotation.FloatRange +private const val MINIMUM_VOLUME_LEVEL = 0.0 +private const val MAXIMUM_VOLUME_LEVEL = 1.0 + /** * The state is returned if we change the speech volume. - * @param level + * @param level volume level must be a value between [0.0..1.0] */ data class SpeechVolume( - @FloatRange(from = 0.0, to = 1.0) + @FloatRange(from = MINIMUM_VOLUME_LEVEL, to = MAXIMUM_VOLUME_LEVEL) val level: Float -) +) { + init { + require(level in MINIMUM_VOLUME_LEVEL..MAXIMUM_VOLUME_LEVEL) { + "Volume level must be between [$MINIMUM_VOLUME_LEVEL..$MAXIMUM_VOLUME_LEVEL]" + } + } +} diff --git a/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApiTest.kt b/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApiTest.kt index 9b4a46aef7d..ca256e914c8 100644 --- a/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApiTest.kt +++ b/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxSpeechApiTest.kt @@ -4,6 +4,7 @@ import android.content.Context import com.mapbox.api.directions.v5.models.VoiceInstructions import com.mapbox.navigation.testing.MainCoroutineRule import com.mapbox.navigation.ui.base.model.Expected +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.voice.VoiceAction import com.mapbox.navigation.ui.voice.VoiceProcessor import com.mapbox.navigation.ui.voice.VoiceResult @@ -85,9 +86,9 @@ class MapboxSpeechApiTest { """.trimIndent() every { mockedVoiceInstructions.announcement() } returns anAnnouncement every { mockedVoiceInstructions.ssmlAnnouncement() } returns aSsmlAnnouncement - val speechCallback: SpeechCallback = mockk() + val speechConsumer: MapboxNavigationConsumer> = mockk() val speechValueSlot = slot>() - every { speechCallback.onSpeech(capture(speechValueSlot)) } just Runs + every { speechConsumer.accept(capture(speechValueSlot)) } just Runs val mockedInstructionFile: File = mockk() val mockedVoiceApi: MapboxVoiceApi = mockk() coEvery { @@ -104,10 +105,10 @@ class MapboxSpeechApiTest { } returns mockedVoiceApi val mapboxSpeechApi = MapboxSpeechApi(aMockedContext, anyAccessToken, anyLanguage) - mapboxSpeechApi.generate(mockedVoiceInstructions, speechCallback) + mapboxSpeechApi.generate(mockedVoiceInstructions, speechConsumer) verify(exactly = 1) { - speechCallback.onSpeech( + speechConsumer.accept( speechValueSlot.captured ) } @@ -129,8 +130,8 @@ class MapboxSpeechApiTest { """.trimIndent() every { mockedVoiceInstructions.announcement() } returns anAnnouncement every { mockedVoiceInstructions.ssmlAnnouncement() } returns aSsmlAnnouncement - val speechCallback: SpeechCallback = mockk() - every { speechCallback.onSpeech(any()) } just Runs + val speechConsumer: MapboxNavigationConsumer> = mockk() + every { speechConsumer.accept(any()) } just Runs val mockedVoiceError: VoiceState.VoiceError = VoiceState.VoiceError( "code: 204, error: No data available" ) @@ -156,10 +157,10 @@ class MapboxSpeechApiTest { VoiceProcessor.process(any()) } returns VoiceResult.VoiceTypeAndAnnouncement.Success(mockedTypeAndAnnouncement) - mapboxSpeechApi.generate(mockedVoiceInstructions, speechCallback) + mapboxSpeechApi.generate(mockedVoiceInstructions, speechConsumer) verify(exactly = 1) { - speechCallback.onSpeech( + speechConsumer.accept( capture(speechErrorSlot) ) } @@ -191,8 +192,8 @@ class MapboxSpeechApiTest { """.trimIndent() every { mockedVoiceInstructions.announcement() } returns anAnnouncement every { mockedVoiceInstructions.ssmlAnnouncement() } returns aSsmlAnnouncement - val speechCallback: SpeechCallback = mockk() - every { speechCallback.onSpeech(any()) } just Runs + val speechConsumer: MapboxNavigationConsumer> = mockk() + every { speechConsumer.accept(any()) } just Runs val mockedVoiceError: VoiceState.VoiceError = VoiceState.VoiceError( "code: 204, error: No data available" ) @@ -216,7 +217,7 @@ class MapboxSpeechApiTest { VoiceProcessor.process(any()) } returns VoiceResult.VoiceTypeAndAnnouncement.Failure(voiceTypeAndAnnouncementError) - mapboxSpeechApi.generate(mockedVoiceInstructions, speechCallback) + mapboxSpeechApi.generate(mockedVoiceInstructions, speechConsumer) assertTrue(exceptions[0] is java.lang.IllegalStateException) assertEquals( @@ -233,7 +234,8 @@ class MapboxSpeechApiTest { val anyAccessToken = "pk.123" val anyLanguage = Locale.US.language val mockedVoiceInstructions: VoiceInstructions = mockk() - val speechCallback: SpeechCallback = mockk() + val speechConsumer: MapboxNavigationConsumer> = + mockk() val mockedVoiceResponse: VoiceState.VoiceResponse = VoiceState.VoiceResponse(mockk()) val mockedVoiceApi: MapboxVoiceApi = mockk() coEvery { @@ -250,7 +252,7 @@ class MapboxSpeechApiTest { } returns mockedVoiceApi val mapboxSpeechApi = MapboxSpeechApi(aMockedContext, anyAccessToken, anyLanguage) - mapboxSpeechApi.generate(mockedVoiceInstructions, speechCallback) + mapboxSpeechApi.generate(mockedVoiceInstructions, speechConsumer) assertTrue(exceptions[0] is java.lang.IllegalStateException) assertEquals( diff --git a/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayerTest.kt b/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayerTest.kt index 0cf142f18e4..8c51bd74e09 100644 --- a/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayerTest.kt +++ b/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/api/MapboxVoiceInstructionsPlayerTest.kt @@ -2,6 +2,7 @@ package com.mapbox.navigation.ui.voice.api import android.content.Context import android.media.AudioManager +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.voice.model.SpeechAnnouncement import com.mapbox.navigation.ui.voice.model.SpeechVolume import com.mapbox.navigation.ui.voice.options.VoiceInstructionsPlayerOptions @@ -87,10 +88,10 @@ class MapboxVoiceInstructionsPlayerTest { mockedVoiceInstructionsPlayerOptions ) val mockedPlay: SpeechAnnouncement = mockedAnnouncement - val voiceInstructionsPlayerCallback: VoiceInstructionsPlayerCallback = mockk() - every { voiceInstructionsPlayerCallback.onDone(any()) } just Runs + val voiceInstructionsPlayerConsumer: MapboxNavigationConsumer = mockk() + every { voiceInstructionsPlayerConsumer.accept(any()) } just Runs - mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerCallback) + mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerConsumer) verify(exactly = 1) { mockedFilePlayer.play(mockedPlay, any()) @@ -99,7 +100,7 @@ class MapboxVoiceInstructionsPlayerTest { mockedTextPlayer.play(mockedPlay, any()) } verify(exactly = 1) { - voiceInstructionsPlayerCallback.onDone(mockedPlay) + voiceInstructionsPlayerConsumer.accept(mockedPlay) } } @@ -140,10 +141,10 @@ class MapboxVoiceInstructionsPlayerTest { mockedVoiceInstructionsPlayerOptions ) val mockedPlay: SpeechAnnouncement = mockedAnnouncement - val voiceInstructionsPlayerCallback: VoiceInstructionsPlayerCallback = mockk() - every { voiceInstructionsPlayerCallback.onDone(any()) } just Runs + val voiceInstructionsPlayerConsumer: MapboxNavigationConsumer = mockk() + every { voiceInstructionsPlayerConsumer.accept(any()) } just Runs - mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerCallback) + mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerConsumer) verify(exactly = 1) { mockedTextPlayer.play(mockedPlay, any()) @@ -152,7 +153,7 @@ class MapboxVoiceInstructionsPlayerTest { mockedFilePlayer.play(mockedPlay, any()) } verify(exactly = 1) { - voiceInstructionsPlayerCallback.onDone(mockedPlay) + voiceInstructionsPlayerConsumer.accept(mockedPlay) } } @@ -199,17 +200,17 @@ class MapboxVoiceInstructionsPlayerTest { mockedVoiceInstructionsPlayerOptions ) val mockedPlay: SpeechAnnouncement = mockedAnnouncement - val voiceInstructionsPlayerCallback: VoiceInstructionsPlayerCallback = mockk() - every { voiceInstructionsPlayerCallback.onDone(any()) } just Runs + val voiceInstructionsPlayerConsumer: MapboxNavigationConsumer = mockk() + every { voiceInstructionsPlayerConsumer.accept(any()) } just Runs - mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerCallback) - mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerCallback) + mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerConsumer) + mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerConsumer) verifyOrder { mockedFilePlayer.play(mockedPlay, any()) - voiceInstructionsPlayerCallback.onDone(mockedPlay) + voiceInstructionsPlayerConsumer.accept(mockedPlay) mockedTextPlayer.play(mockedPlay, any()) - voiceInstructionsPlayerCallback.onDone(mockedPlay) + voiceInstructionsPlayerConsumer.accept(mockedPlay) } } @@ -413,10 +414,10 @@ class MapboxVoiceInstructionsPlayerTest { mockedVoiceInstructionsPlayerOptions ) val mockedPlay: SpeechAnnouncement = mockedAnnouncement - val voiceInstructionsPlayerCallback: VoiceInstructionsPlayerCallback = mockk() - every { voiceInstructionsPlayerCallback.onDone(any()) } just Runs + val voiceInstructionsPlayerConsumer: MapboxNavigationConsumer = mockk() + every { voiceInstructionsPlayerConsumer.accept(any()) } just Runs - mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerCallback) + mapboxVoiceInstructionsPlayer.play(mockedPlay, voiceInstructionsPlayerConsumer) verify(exactly = 1) { mockedAudioFocusDelegate.requestFocus() diff --git a/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/model/SpeechVolumeTest.kt b/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/model/SpeechVolumeTest.kt new file mode 100644 index 00000000000..7a56682cde9 --- /dev/null +++ b/libnavui-voice/src/test/java/com/mapbox/navigation/ui/voice/model/SpeechVolumeTest.kt @@ -0,0 +1,24 @@ +package com.mapbox.navigation.ui.voice.model + +import org.junit.Assert.assertEquals +import org.junit.Test + +class SpeechVolumeTest { + + @Test(expected = IllegalArgumentException::class) + fun `invalid speech volume - less than minimum`() { + SpeechVolume(-1.0f) + } + + @Test(expected = IllegalArgumentException::class) + fun `invalid speech volume - greater than maximum`() { + SpeechVolume(2.0f) + } + + @Test + fun `valid speech volume - sanity`() { + val speechVolume = SpeechVolume(0.5f) + + assertEquals(0.5f, speechVolume.level) + } +} diff --git a/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt b/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt index 0cce3d111ac..4f776deb45a 100644 --- a/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt +++ b/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt @@ -48,6 +48,7 @@ import com.mapbox.navigation.core.trip.session.VoiceInstructionsObserver import com.mapbox.navigation.examples.core.databinding.LayoutActivityNavigationBinding import com.mapbox.navigation.examples.util.Utils import com.mapbox.navigation.ui.base.model.Expected +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.maneuver.api.ManeuverCallback import com.mapbox.navigation.ui.maneuver.api.MapboxManeuverApi import com.mapbox.navigation.ui.maneuver.api.StepDistanceRemainingCallback @@ -76,8 +77,6 @@ import com.mapbox.navigation.ui.tripprogress.model.TripProgressUpdateFormatter import com.mapbox.navigation.ui.utils.internal.ifNonNull import com.mapbox.navigation.ui.voice.api.MapboxSpeechApi import com.mapbox.navigation.ui.voice.api.MapboxVoiceInstructionsPlayer -import com.mapbox.navigation.ui.voice.api.SpeechCallback -import com.mapbox.navigation.ui.voice.api.VoiceInstructionsPlayerCallback import com.mapbox.navigation.ui.voice.model.SpeechAnnouncement import com.mapbox.navigation.ui.voice.model.SpeechError import com.mapbox.navigation.ui.voice.model.SpeechValue @@ -172,33 +171,34 @@ class MapboxNavigationActivity : } } - private val voiceInstructionsPlayerCallback: VoiceInstructionsPlayerCallback = - object : VoiceInstructionsPlayerCallback { - override fun onDone(announcement: SpeechAnnouncement) { - speechAPI.clean(announcement) + private val voiceInstructionsPlayerCallback = + object : MapboxNavigationConsumer { + override fun accept(consumer: SpeechAnnouncement) { + speechAPI.clean(consumer) } } - private val speechCallback = object : SpeechCallback { - override fun onSpeech(state: Expected) { - when (state) { - is Expected.Success -> { - val currentSpeechValue = state.value - voiceInstructionsPlayer?.play( - currentSpeechValue.announcement, - voiceInstructionsPlayerCallback - ) - } - is Expected.Failure -> { - val currentSpeechError = state.error - voiceInstructionsPlayer?.play( - currentSpeechError.fallback, - voiceInstructionsPlayerCallback - ) + private val speechCallback = + object : MapboxNavigationConsumer> { + override fun accept(consumer: Expected) { + when (consumer) { + is Expected.Success -> { + val currentSpeechValue = consumer.value + voiceInstructionsPlayer?.play( + currentSpeechValue.announcement, + voiceInstructionsPlayerCallback + ) + } + is Expected.Failure -> { + val currentSpeechError = consumer.error + voiceInstructionsPlayer?.play( + currentSpeechError.fallback, + voiceInstructionsPlayerCallback + ) + } } } } - } private val mapMatcherResultObserver = object : MapMatcherResultObserver { override fun onNewMapMatcherResult(mapMatcherResult: MapMatcherResult) { diff --git a/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxVoiceActivity.kt b/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxVoiceActivity.kt index 05257f68b9d..5b0bdcbada9 100644 --- a/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxVoiceActivity.kt +++ b/test-app/src/main/java/com/mapbox/navigation/examples/core/MapboxVoiceActivity.kt @@ -45,6 +45,7 @@ import com.mapbox.navigation.core.trip.session.RouteProgressObserver import com.mapbox.navigation.core.trip.session.VoiceInstructionsObserver import com.mapbox.navigation.examples.core.databinding.LayoutActivityVoiceBinding import com.mapbox.navigation.ui.base.model.Expected +import com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer import com.mapbox.navigation.ui.maps.camera.NavigationCamera import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSourceOptions @@ -60,8 +61,6 @@ import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineOptions import com.mapbox.navigation.ui.maps.route.line.model.RouteLine import com.mapbox.navigation.ui.voice.api.MapboxSpeechApi import com.mapbox.navigation.ui.voice.api.MapboxVoiceInstructionsPlayer -import com.mapbox.navigation.ui.voice.api.SpeechCallback -import com.mapbox.navigation.ui.voice.api.VoiceInstructionsPlayerCallback import com.mapbox.navigation.ui.voice.model.SpeechAnnouncement import com.mapbox.navigation.ui.voice.model.SpeechError import com.mapbox.navigation.ui.voice.model.SpeechValue @@ -153,41 +152,43 @@ class MapboxVoiceActivity : } } - private val voiceInstructionsPlayerCallback: VoiceInstructionsPlayerCallback = - object : VoiceInstructionsPlayerCallback { - override fun onDone(announcement: SpeechAnnouncement) { - speechAPI.clean(announcement) + private val voiceInstructionsPlayerCallback = + object : MapboxNavigationConsumer { + override fun accept(consumer: SpeechAnnouncement) { + speechAPI.clean(consumer) } } - private val speechCallback = object : SpeechCallback { - override fun onSpeech(state: Expected) { - when (state) { - is Expected.Success -> { - val currentSpeechValue = state.value - if (isFirst) { - firstPlay = currentSpeechValue.announcement - isFirst = false + private val speechCallback = + object : MapboxNavigationConsumer> { + override fun accept(consumer: Expected) { + when (consumer) { + is Expected.Success -> { + val currentSpeechValue = consumer.value + if (isFirst) { + firstPlay = currentSpeechValue.announcement + isFirst = false + } + voiceInstructionsPlayer?.play( + currentSpeechValue.announcement, + voiceInstructionsPlayerCallback + ) + } + is Expected.Failure -> { + val currentSpeechError = consumer.error + Log.e( + "VoiceActivity", + "Error playing the voice instruction: " + + "${currentSpeechError.errorMessage}" + ) + voiceInstructionsPlayer?.play( + currentSpeechError.fallback, + voiceInstructionsPlayerCallback + ) } - voiceInstructionsPlayer?.play( - currentSpeechValue.announcement, - voiceInstructionsPlayerCallback - ) - } - is Expected.Failure -> { - val currentSpeechError = state.error - Log.e( - "VoiceActivity", - "Error playing the voice instruction: ${currentSpeechError.errorMessage}" - ) - voiceInstructionsPlayer?.play( - currentSpeechError.fallback, - voiceInstructionsPlayerCallback - ) } } } - } private val voiceInstructionsObserver = object : VoiceInstructionsObserver { override fun onNewVoiceInstructions(voiceInstructions: VoiceInstructions) {