Skip to content

Commit

Permalink
Integrate new routing logic with deprecation flow
Browse files Browse the repository at this point in the history
  • Loading branch information
adhiamboperes committed Feb 28, 2024
1 parent 971892b commit e5a396c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class SplashActivityPresenter @Inject constructor(
)
}
StartupMode.ONBOARDING_FLOW_V2 -> {
computeRoute()
getProfileOnboardingState()
}
else -> {
// In all other cases (including errors when the startup state fails to load or is
Expand All @@ -309,65 +309,64 @@ class SplashActivityPresenter @Inject constructor(
}
}

private fun computeRoute() {
// Use SplashActivityViewModel to retrieve the profile type and onboarding status
// Based on the returned profile information, compute route as follows:
when (getProfileOnboardingState()) {
ProfileOnboardingState.NEW_INSTALL -> {
activity.startActivity(OnboardingActivity.createOnboardingActivity(activity))
activity.finish()
}
ProfileOnboardingState.SOLE_LEARNER_PROFILE -> {
// TODO retrieve profileId and pass to intent
activity.startActivity(HomeActivity.createHomeActivity(activity, null))
activity.finish()
}
else -> {
activity.startActivity(ProfileChooserActivity.createProfileChooserActivity(activity))
activity.finish()
}
}
}

/** Returns the state of the app based on the number of existing profiles. */
private fun getProfileOnboardingState(): ProfileOnboardingState {
var profileList = listOf<Profile>()
profileManagementController.getProfiles().toLiveData().observe(
private fun getProfileOnboardingState() {
appStartupStateController.getProfileOnboardingState().toLiveData().observe(
activity,
{ result ->
when (result) {
is AsyncResult.Success -> {
profileList = result.value
computeLoginRoute(result.value)
}
is AsyncResult.Failure -> {
oppiaLogger.e(
"SplashActivity",
"Encountered unexpected non-successful result when fetching profiles",
"Encountered unexpected non-successful result when fetching onboarding state",
result.error
)
}
else -> {} // no-op
is AsyncResult.Pending -> {}
}
}
)
}

return when {
profileList.size > 1 -> {
ProfileOnboardingState.MULTIPLE_PROFILES
private fun computeLoginRoute(onboardingState: ProfileOnboardingState) {
when (onboardingState) {
ProfileOnboardingState.NEW_INSTALL -> {
activity.startActivity(OnboardingActivity.createOnboardingActivity(activity))
activity.finish()
}
profileList.size == 1 -> {
if (profileList.first().isAdmin && profileList.first().hasPin) {
ProfileOnboardingState.ADMIN_PROFILE_ONLY
} else {
ProfileOnboardingState.SOLE_LEARNER_PROFILE
}
ProfileOnboardingState.SOLE_LEARNER_PROFILE -> {
profileManagementController.getProfiles().toLiveData().observe(
activity,
{ result ->
when (result) {
is AsyncResult.Success -> {
val internalProfileId = getSoleLearnerProfile(result.value)?.id?.internalId
activity.startActivity(HomeActivity.createHomeActivity(activity, internalProfileId))
activity.finish()
}
is AsyncResult.Pending -> {} // no-op
is AsyncResult.Failure -> {
oppiaLogger.e(
"SplashActivity", "Failed to retrieve the list of profiles", result.error
)
}
}
}
)
}
else -> {
ProfileOnboardingState.NEW_INSTALL
activity.startActivity(ProfileChooserActivity.createProfileChooserActivity(activity))
activity.finish()
}
}
}

private fun getSoleLearnerProfile(profiles: List<Profile>): Profile? {
return profiles.find { it.isAdmin }
}

private fun computeInitStateDataProvider(): DataProvider<SplashInitState> {
val startupStateDataProvider = appStartupStateController.getAppStartupState()
val systemAppLanguageLocaleDataProvider = translationController.getSystemLanguageLocale()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@ import org.oppia.android.app.model.AppStartupState
import org.oppia.android.app.model.AppStartupState.BuildFlavorNoticeMode
import org.oppia.android.app.model.AppStartupState.StartupMode
import org.oppia.android.app.model.BuildFlavor
import org.oppia.android.app.model.DeprecationResponseDatabase
import org.oppia.android.app.model.OnboardingState
import org.oppia.android.app.model.ProfileOnboardingState
import org.oppia.android.data.persistence.PersistentCacheStore
import org.oppia.android.domain.oppialogger.OppiaLogger
import org.oppia.android.domain.profile.ProfileManagementController
import org.oppia.android.util.data.DataProvider
import org.oppia.android.util.data.DataProviders.Companion.combineWith
import org.oppia.android.util.data.DataProviders.Companion.transform
import org.oppia.android.util.extensions.getStringFromBundle
import org.oppia.android.util.locale.OppiaLocale
import org.oppia.android.util.platformparameter.EnableAppAndOsDeprecation
import org.oppia.android.util.platformparameter.EnableOnboardingFlowV2
import org.oppia.android.util.platformparameter.PlatformParameterValue
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton

private const val APP_STARTUP_STATE_PROVIDER_ID = "app_startup_state_data_provider_id"
private const val PROFILE_ONBOARDING_STATE_PROVIDER_ID = "profile_onboarding_state_data_provider_id"

/** Controller for persisting and retrieving the user's initial app state upon opening the app. */
@Singleton
Expand All @@ -30,10 +29,7 @@ class AppStartupStateController @Inject constructor(
private val machineLocale: OppiaLocale.MachineLocale,
private val currentBuildFlavor: BuildFlavor,
private val deprecationController: DeprecationController,
@EnableAppAndOsDeprecation
private val enableAppAndOsDeprecation: Provider<PlatformParameterValue<Boolean>>,
@EnableOnboardingFlowV2
private val enableOnboardingFlowV2: PlatformParameterValue<Boolean>
private val profileManagementController: ProfileManagementController
) {
private val onboardingFlowStore by lazy {
cacheStoreFactory.create("on_boarding_flow", OnboardingState.getDefaultInstance())
Expand Down Expand Up @@ -107,7 +103,10 @@ class AppStartupStateController @Inject constructor(
APP_STARTUP_STATE_PROVIDER_ID
) { onboardingState, deprecationResponseDatabase ->
AppStartupState.newBuilder().apply {
startupMode = computeAppStartupMode(onboardingState, deprecationResponseDatabase)
startupMode = deprecationController.processStartUpMode(
onboardingState,
deprecationResponseDatabase
)
buildFlavorNoticeMode = computeBuildNoticeMode(onboardingState, startupMode)
}.build()
}
Expand All @@ -130,24 +129,6 @@ class AppStartupStateController @Inject constructor(
}
}

private fun computeAppStartupMode(
onboardingState: OnboardingState,
deprecationResponseDatabase: DeprecationResponseDatabase
): StartupMode {
// Process and return either a StartupMode.APP_IS_DEPRECATED, StartupMode.USER_IS_ONBOARDED or
// StartupMode.USER_NOT_YET_ONBOARDED if the app and OS deprecation feature flag is not enabled.
if (!enableAppAndOsDeprecation.get().value) {
return when {
hasAppExpired() -> StartupMode.APP_IS_DEPRECATED
onboardingState.alreadyOnboardedApp -> StartupMode.USER_IS_ONBOARDED
enableOnboardingFlowV2.value -> StartupMode.ONBOARDING_FLOW_V2
else -> StartupMode.USER_NOT_YET_ONBOARDED
}
}

return deprecationController.processStartUpMode(onboardingState, deprecationResponseDatabase)
}

private fun computeBuildNoticeMode(
onboardingState: OnboardingState,
startupMode: StartupMode
Expand Down Expand Up @@ -194,4 +175,26 @@ class AppStartupStateController @Inject constructor(
expirationDate?.isBeforeToday() ?: true
} else false
}

/** Returns the state of the app based on the number and type of existing profiles. */
fun getProfileOnboardingState(): DataProvider<ProfileOnboardingState> {
return profileManagementController.getProfiles()
.transform(PROFILE_ONBOARDING_STATE_PROVIDER_ID) { profileList ->
when {
profileList.size > 1 -> {
ProfileOnboardingState.MULTIPLE_PROFILES
}
profileList.size == 1 -> {
if (profileList.first().isAdmin && profileList.first().pin.isNotBlank()) {
ProfileOnboardingState.ADMIN_PROFILE_ONLY
} else {
ProfileOnboardingState.SOLE_LEARNER_PROFILE
}
}
else -> {
ProfileOnboardingState.NEW_INSTALL
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.oppia.android.util.data.DataProvider
import org.oppia.android.util.data.DataProviders
import org.oppia.android.util.data.DataProviders.Companion.transform
import org.oppia.android.util.extensions.getVersionCode
import org.oppia.android.util.platformparameter.EnableOnboardingFlowV2
import org.oppia.android.util.platformparameter.ForcedAppUpdateVersionCode
import org.oppia.android.util.platformparameter.LowestSupportedApiLevel
import org.oppia.android.util.platformparameter.OptionalAppUpdateVersionCode
Expand All @@ -41,7 +42,9 @@ class DeprecationController @Inject constructor(
@ForcedAppUpdateVersionCode
private val forcedAppUpdateVersionCode: Provider<PlatformParameterValue<Int>>,
@LowestSupportedApiLevel
private val lowestSupportedApiLevel: Provider<PlatformParameterValue<Int>>
private val lowestSupportedApiLevel: Provider<PlatformParameterValue<Int>>,
@EnableOnboardingFlowV2
private val enableOnboardingFlowV2: PlatformParameterValue<Boolean>
) {
/** Create an instance of [PersistentCacheStore] that contains a [DeprecationResponseDatabase]. */
private val deprecationStore by lazy {
Expand Down Expand Up @@ -173,6 +176,10 @@ class DeprecationController @Inject constructor(
return StartupMode.OPTIONAL_UPDATE_AVAILABLE
}

if (enableOnboardingFlowV2.value) {
return StartupMode.ONBOARDING_FLOW_V2
}

return StartupMode.USER_IS_ONBOARDED
} else return StartupMode.USER_NOT_YET_ONBOARDED
}
Expand Down

0 comments on commit e5a396c

Please sign in to comment.