diff --git a/app/src/main/kotlin/com/wire/android/di/AppModule.kt b/app/src/main/kotlin/com/wire/android/di/AppModule.kt index c1a94d5fd87..d2e0463b37d 100644 --- a/app/src/main/kotlin/com/wire/android/di/AppModule.kt +++ b/app/src/main/kotlin/com/wire/android/di/AppModule.kt @@ -40,6 +40,7 @@ import dagger.hilt.InstallIn import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent import linc.com.amplituda.Amplituda +import javax.inject.Named import javax.inject.Qualifier import javax.inject.Singleton @@ -110,4 +111,8 @@ object AppModule { @Provides fun provideAudioManager(@ApplicationContext context: Context): AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager + + @Provides + @Named("useNewLoginForDefaultBackend") + fun provideUseNewLoginForDefaultBackend(): Boolean = BuildConfig.USE_NEW_LOGIN_FOR_DEFAULT_BACKEND } diff --git a/app/src/main/kotlin/com/wire/android/navigation/LoginTypeSelector.kt b/app/src/main/kotlin/com/wire/android/navigation/LoginTypeSelector.kt index 3d8b2afb2e4..c88688cf4c5 100644 --- a/app/src/main/kotlin/com/wire/android/navigation/LoginTypeSelector.kt +++ b/app/src/main/kotlin/com/wire/android/navigation/LoginTypeSelector.kt @@ -19,16 +19,12 @@ package com.wire.android.navigation import com.wire.android.config.DefaultServerConfig import com.wire.android.di.KaliumCoreLogic -import com.wire.android.util.dispatchers.DispatcherProvider import com.wire.kalium.logic.CoreLogic import com.wire.kalium.logic.configuration.server.ServerConfig import com.wire.kalium.logic.feature.auth.LoginContext -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.stateIn import javax.inject.Inject +import javax.inject.Named import javax.inject.Singleton /** @@ -37,21 +33,9 @@ import javax.inject.Singleton */ @Singleton class LoginTypeSelector @Inject constructor( - dispatcherProvider: DispatcherProvider, @KaliumCoreLogic private val coreLogic: CoreLogic, + @Named("useNewLoginForDefaultBackend") private val useNewLoginForDefaultBackend: Boolean, ) { - private val scope = CoroutineScope(SupervisorJob() + dispatcherProvider.default()) - - // StateFlow of the login context for the default server config, so that the value is kept ready to use and the use case doesn't need - // to be executed every time the app needs to determine if the new login flow can be used. - private lateinit var loginContextForDefaultServerConfigStateFlow: StateFlow - - // it needs to be initialised before navigation is setup - suspend fun init() { - if (!::loginContextForDefaultServerConfigStateFlow.isInitialized) { - loginContextForDefaultServerConfigStateFlow = loginContextFlow(DefaultServerConfig).stateIn(scope) - } - } /** * Observe the [LoginContext] for the given [ServerConfig.Links]. @@ -65,11 +49,11 @@ class LoginTypeSelector @Inject constructor( // if the server links are provided, get the login context for the given server links and check if it's enterprise login serverLinks != null -> loginContextFlow(serverLinks).first() == LoginContext.EnterpriseLogin // otherwise, use the function for the default server config links to determine if the new login flow can be used - else -> loginContextForDefaultServerConfigStateFlow.value == LoginContext.EnterpriseLogin + else -> canUseNewLogin() } /** * Determine if the new login flow can be used for the default [ServerConfig.Links] - [DefaultServerConfig]. */ - fun canUseNewLogin() = loginContextForDefaultServerConfigStateFlow.value == LoginContext.EnterpriseLogin + fun canUseNewLogin() = useNewLoginForDefaultBackend } diff --git a/app/src/main/kotlin/com/wire/android/ui/WireActivity.kt b/app/src/main/kotlin/com/wire/android/ui/WireActivity.kt index 323f87e79fd..0fddadd3247 100644 --- a/app/src/main/kotlin/com/wire/android/ui/WireActivity.kt +++ b/app/src/main/kotlin/com/wire/android/ui/WireActivity.kt @@ -185,7 +185,6 @@ class WireActivity : AppCompatActivity() { legalHoldRequestedViewModel.observeLegalHoldRequest() appLogger.i("$TAG init login type selector") - loginTypeSelector.init() appLogger.i("$TAG start destination") val startDestination = when (viewModel.initialAppState()) { diff --git a/app/src/test/kotlin/com/wire/android/navigation/LoginTypeSelectorTest.kt b/app/src/test/kotlin/com/wire/android/navigation/LoginTypeSelectorTest.kt index 1be2160e5e2..fe0762acc5e 100644 --- a/app/src/test/kotlin/com/wire/android/navigation/LoginTypeSelectorTest.kt +++ b/app/src/test/kotlin/com/wire/android/navigation/LoginTypeSelectorTest.kt @@ -18,7 +18,6 @@ package com.wire.android.navigation import com.wire.android.config.DefaultServerConfig -import com.wire.android.config.TestDispatcherProvider import com.wire.android.util.newServerConfig import com.wire.kalium.logic.CoreLogic import com.wire.kalium.logic.configuration.server.ServerConfig @@ -34,75 +33,60 @@ import org.amshove.kluent.internal.assertEquals import org.junit.jupiter.api.Test class LoginTypeSelectorTest { - private val dispatcherProvider = TestDispatcherProvider() @Test fun `given default config with enterprise context, then can use new login`() = - runTest(dispatcherProvider.main()) { + runTest { val (_, loginTypeSelector) = Arrangement() .withContextFlowForConfig(DefaultServerConfig, flowOf(LoginContext.EnterpriseLogin)) - .arrange() + .arrange(true) val result = loginTypeSelector.canUseNewLogin() assertEquals(true, result) } @Test fun `given custom config with enterprise context, then can use new login`() = - runTest(dispatcherProvider.main()) { + runTest { val config = newServerConfig(1) val (_, loginTypeSelector) = Arrangement() .withContextFlowForConfig(DefaultServerConfig, flowOf(LoginContext.FallbackLogin)) .withContextFlowForConfig(config.links, flowOf(LoginContext.EnterpriseLogin)) - .arrange() + .arrange(true) val result = loginTypeSelector.canUseNewLogin(config.links) assertEquals(true, result) } @Test fun `given default config with fallback context, then cannot use new login`() = - runTest(dispatcherProvider.main()) { + runTest { val (_, loginTypeSelector) = Arrangement() .withContextFlowForConfig(DefaultServerConfig, flowOf(LoginContext.FallbackLogin)) - .arrange() + .arrange(false) val result = loginTypeSelector.canUseNewLogin() assertEquals(false, result) } @Test fun `given custom config with fallback context, then cannot use new login`() = - runTest(dispatcherProvider.main()) { + runTest { val config = newServerConfig(1) val (_, loginTypeSelector) = Arrangement() .withContextFlowForConfig(DefaultServerConfig, flowOf(LoginContext.EnterpriseLogin)) .withContextFlowForConfig(config.links, flowOf(LoginContext.FallbackLogin)) - .arrange() + .arrange(true) val result = loginTypeSelector.canUseNewLogin(config.links) assertEquals(false, result) } - @Test - fun `given default config with fallback context, when context changes to enterprise, then can use new login after it changes`() = - runTest(dispatcherProvider.main()) { - val contextFlow = MutableStateFlow(LoginContext.FallbackLogin) - val (_, loginTypeSelector) = Arrangement() - .withContextFlowForConfig(DefaultServerConfig, contextFlow) - .arrange() - val resultBeforeChange = loginTypeSelector.canUseNewLogin() - assertEquals(false, resultBeforeChange) - contextFlow.value = LoginContext.EnterpriseLogin - val resultAfterChange = loginTypeSelector.canUseNewLogin() - assertEquals(true, resultAfterChange) - } - @Test fun `given custom config with fallback context, when context changes to enterprise, then can use new login after it changes`() = - runTest(dispatcherProvider.main()) { + runTest { val config = newServerConfig(1) val contextFlow = MutableStateFlow(LoginContext.FallbackLogin) val (_, loginTypeSelector) = Arrangement() .withContextFlowForConfig(DefaultServerConfig, flowOf(LoginContext.FallbackLogin)) .withContextFlowForConfig(config.links, contextFlow) - .arrange() + .arrange(true) val resultBeforeChange = loginTypeSelector.canUseNewLogin(config.links) assertEquals(false, resultBeforeChange) contextFlow.value = LoginContext.EnterpriseLogin @@ -118,7 +102,7 @@ class LoginTypeSelectorTest { MockKAnnotations.init(this, relaxUnitFun = true) } - suspend fun arrange() = this to LoginTypeSelector(dispatcherProvider, coreLogic).also { it.init() } + fun arrange(useNewLoginForDefaultBackend: Boolean) = this to LoginTypeSelector(coreLogic, useNewLoginForDefaultBackend) fun withContextFlowForConfig(config: ServerConfig.Links, contextFlow: Flow) = apply { coEvery { coreLogic.getGlobalScope().observeLoginContext(config) } returns contextFlow diff --git a/buildSrc/src/main/kotlin/customization/FeatureConfigs.kt b/buildSrc/src/main/kotlin/customization/FeatureConfigs.kt index ef9a17f2a25..171db140cbd 100644 --- a/buildSrc/src/main/kotlin/customization/FeatureConfigs.kt +++ b/buildSrc/src/main/kotlin/customization/FeatureConfigs.kt @@ -107,6 +107,8 @@ enum class FeatureConfigs(val value: String, val configType: ConfigType) { PAGINATED_CONVERSATION_LIST_ENABLED("paginated_conversation_list_enabled", ConfigType.BOOLEAN), PUBLIC_CHANNELS_ENABLED("public_channels_enabled", ConfigType.BOOLEAN), + + USE_NEW_LOGIN_FOR_DEFAULT_BACKEND("use_new_login_for_default_backend", ConfigType.BOOLEAN), /** * Anonymous Analytics */ diff --git a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt index f6c8854e6a3..bacee80e77c 100644 --- a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt +++ b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt @@ -63,9 +63,9 @@ class AnonymousAnalyticsRecorderImpl( Countly.sharedInstance()?.init(countlyConfig) val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0) - val globalSegmentations = mapOf( + val globalSegmentations = mapOf( APP_NAME to AnalyticsEventConstants.APP_NAME_ANDROID, - APP_VERSION to packageInfo.versionName + APP_VERSION to packageInfo.versionName.orEmpty() ) Countly.sharedInstance()?.views()?.setGlobalViewSegmentation(globalSegmentations) isConfigured = true diff --git a/default.json b/default.json index 1ad71a154cb..4e9e83bcc86 100644 --- a/default.json +++ b/default.json @@ -134,5 +134,6 @@ "picture_in_picture_enabled": false, "paginated_conversation_list_enabled": false, "should_display_release_notes": true, - "public_channels_enabled": false + "public_channels_enabled": false, + "use_new_login_for_default_backend": true }