diff --git a/app/src/main/java/org/oppia/android/app/options/AudioLanguageSelectionViewModel.kt b/app/src/main/java/org/oppia/android/app/options/AudioLanguageSelectionViewModel.kt index b2de15c0deb..2a3cc2e35e8 100644 --- a/app/src/main/java/org/oppia/android/app/options/AudioLanguageSelectionViewModel.kt +++ b/app/src/main/java/org/oppia/android/app/options/AudioLanguageSelectionViewModel.kt @@ -54,10 +54,9 @@ class AudioLanguageSelectionViewModel @Inject constructor( val selectedLanguage = MutableLiveData() /** Sets the list of audio languages supported by the app based on [OppiaLanguage]. */ - // TODO(#6020): Replace getSupportedAppLanguages with an audio languages specific API. val supportedOppiaLanguagesLiveData: LiveData> = Transformations.map( - translationController.getSupportedAppLanguages().toLiveData() + translationController.getSupportedAudioLanguages().toLiveData() ) { supportedLanguagesResult -> when (supportedLanguagesResult) { is AsyncResult.Failure -> { diff --git a/domain/src/main/java/org/oppia/android/domain/translation/TranslationController.kt b/domain/src/main/java/org/oppia/android/domain/translation/TranslationController.kt index 2faf2cfa10a..1a88d1b1be3 100644 --- a/domain/src/main/java/org/oppia/android/domain/translation/TranslationController.kt +++ b/domain/src/main/java/org/oppia/android/domain/translation/TranslationController.kt @@ -54,6 +54,8 @@ private const val AUDIO_TRANSLATION_CONTENT_LANG_RES_DATA_PROVIDER_ID = private const val AUDIO_TRANSLATION_CONTENT_SELECTION_DATA_PROVIDER_ID = "audio_translation_content_selection" private const val SUPPORTED_AUDIO_LANGUAGES_DATA_PROVIDER_ID = "supported_audio_languages" +private const val SUPPORTED_AUDIO_LANGUAGES_LIST_DATA_PROVIDER_ID = + "supported_audio_languages_list" private const val UPDATE_AUDIO_TRANSLATION_CONTENT_DATA_PROVIDER_ID = "update_audio_translation_content" private const val PROFILE_AUDIO_LANGUAGE_PROVIDER_ID = "profile_audio_language" @@ -133,6 +135,23 @@ class TranslationController @Inject constructor( } } + /** + * Returns a data provider for a list of [OppiaLanguage] which can be passed to + * [updateAudioTranslationContentLanguage]. + * + * Note that this list may differ from [getSupportedAppLanguages] since some languages support + * audio voiceovers but not app strings (e.g. Hinglish). + */ + fun getSupportedAudioLanguages(): DataProvider> { + return dataProviders.createInMemoryDataProvider( + SUPPORTED_AUDIO_LANGUAGES_LIST_DATA_PROVIDER_ID + ) { + languageConfigRetriever.loadSupportedLanguages().languageDefinitionsList.filter { + it.hasAudioTranslationId() + }.map { it.language } + } + } + /** * Returns a data provider for a [OppiaLocale.DisplayLocale] corresponding to the user's selected * language for app strings (see [getAppLanguage]). @@ -311,14 +330,13 @@ class TranslationController @Inject constructor( fun getAudioTranslationContentLocale( profileId: ProfileId ): DataProvider { - // TODO(#6020): Replace getSupportedAppLanguages with an audio languages specific API. val resolvedLanguageProvider = getAudioTranslationContentLanguageSelection(profileId).combineWith( - getSupportedAppLanguages(), SUPPORTED_AUDIO_LANGUAGES_DATA_PROVIDER_ID - ) { audioLanguageSelection, supportedAppLanguages -> + getSupportedAudioLanguages(), SUPPORTED_AUDIO_LANGUAGES_DATA_PROVIDER_ID + ) { audioLanguageSelection, supportedAudioLanguages -> // Before a profile sets an audio language, LANGUAGE_UNSPECIFIED is always returned. // In some cases, a language might not be supported but has a fallback configured. - if (audioLanguageSelection.selectedLanguage in supportedAppLanguages || + if (audioLanguageSelection.selectedLanguage in supportedAudioLanguages || audioLanguageSelection.selectionTypeCase == SelectionTypeCase.USE_APP_LANGUAGE || audioLanguageSelection.selectedLanguage == OppiaLanguage.LANGUAGE_UNSPECIFIED ) { diff --git a/domain/src/test/java/org/oppia/android/domain/translation/TranslationControllerTest.kt b/domain/src/test/java/org/oppia/android/domain/translation/TranslationControllerTest.kt index 656978263ab..980a138972d 100644 --- a/domain/src/test/java/org/oppia/android/domain/translation/TranslationControllerTest.kt +++ b/domain/src/test/java/org/oppia/android/domain/translation/TranslationControllerTest.kt @@ -1178,7 +1178,7 @@ class TranslationControllerTest { } @Test - fun testGetAudioLocale_updateLanguageToHinglish_returnsEnglishLocale() { + fun testGetAudioLocale_updateLanguageToHinglish_returnsHinglishLocale() { forceDefaultLocale(Locale.ROOT) ensureAudioTranslationsLanguageIsUpdatedTo(PROFILE_ID_0, HINGLISH) @@ -1187,6 +1187,22 @@ class TranslationControllerTest { val locale = monitorFactory.waitForNextSuccessfulResult(localeProvider) val context = locale.localeContext assertThat(context.usageMode).isEqualTo(AUDIO_TRANSLATIONS) + assertThat(context.languageDefinition.language).isEqualTo(HINGLISH) + assertThat(context.regionDefinition.region).isEqualTo(REGION_UNSPECIFIED) + } + + @Test + fun testGetAudioLocale_updateLanguageToPortuguese_returnsEnglishLocale() { + forceDefaultLocale(Locale.ROOT) + ensureAudioTranslationsLanguageIsUpdatedTo(PROFILE_ID_0, PORTUGUESE) + + val localeProvider = translationController.getAudioTranslationContentLocale(PROFILE_ID_0) + + val locale = monitorFactory.waitForNextSuccessfulResult(localeProvider) + val context = locale.localeContext + assertThat(context.usageMode).isEqualTo(AUDIO_TRANSLATIONS) + // PORTUGUESE does not have an audio_translation_id, so it is unsupported for audio translations. + // Therefore, it should fall back to ENGLISH. assertThat(context.languageDefinition.language).isEqualTo(ENGLISH) // This region comes from the default locale. assertThat(context.regionDefinition.region).isEqualTo(REGION_UNSPECIFIED) @@ -2036,6 +2052,20 @@ class TranslationControllerTest { .containsExactly(ARABIC, ENGLISH, HINDI, BRAZILIAN_PORTUGUESE, SWAHILI, NIGERIAN_PIDGIN) } + @Test + fun testGetSupportedAudioLanguages_returnsAudioLanguageDefinitions() { + val languageListProvider = translationController.getSupportedAudioLanguages() + val languageListData = monitorFactory.waitForNextSuccessfulResult(languageListProvider) + + // Audio languages include HINGLISH which has an audio_translation_id but no app_string_id, + // so it correctly appears here but not in getSupportedAppLanguages(). This is a change + // detector test to ensure the audio language selection system provides exactly the list of + // intended languages. + assertThat(languageListData).containsExactly( + ARABIC, ENGLISH, HINDI, HINGLISH, BRAZILIAN_PORTUGUESE, SWAHILI, NIGERIAN_PIDGIN + ) + } + private fun setUpTestApplicationComponent() { ApplicationProvider.getApplicationContext().inject(this) }