From 01d5526b04fd24d9f0de666ba8a765e69f016cd8 Mon Sep 17 00:00:00 2001 From: Elly Kitoto Date: Fri, 10 Jan 2025 14:37:45 +0300 Subject: [PATCH] Implement functionality to skip login and data sync Signed-off-by: Elly Kitoto --- .../main/kotlin/project-properties.gradle.kts | 5 +- android/quest/build.gradle.kts | 2 +- .../quest/ui/appsetting/AppSettingActivity.kt | 5 +- .../ui/appsetting/AppSettingViewModel.kt | 14 ++-- .../fhircore/quest/ui/login/LoginActivity.kt | 2 - .../fhircore/quest/ui/main/AppMainActivity.kt | 10 ++- .../quest/ui/main/AppMainViewModel.kt | 64 +++++++++---------- .../quest/ui/main/components/AppDrawer.kt | 19 +++--- .../fhircore/quest/ui/pin/PinLoginActivity.kt | 34 ++++------ .../quest/ui/register/RegisterScreen.kt | 3 +- .../ui/usersetting/UserSettingFragment.kt | 3 +- 11 files changed, 76 insertions(+), 85 deletions(-) diff --git a/android/buildSrc/src/main/kotlin/project-properties.gradle.kts b/android/buildSrc/src/main/kotlin/project-properties.gradle.kts index 47b9fb752c5..0bf3cf73a0e 100644 --- a/android/buildSrc/src/main/kotlin/project-properties.gradle.kts +++ b/android/buildSrc/src/main/kotlin/project-properties.gradle.kts @@ -1,5 +1,4 @@ -import org.gradle.kotlin.dsl.extra -import java.io.File + import java.io.FileInputStream import java.io.FileNotFoundException import java.io.InputStreamReader @@ -20,6 +19,7 @@ fun readProperties(file: String): Properties { // Set required FHIR core properties val requiredFhirProperties = listOf( + "SKIP_AUTHENTICATION", "URL", "FHIR_BASE_URL", "OAUTH_BASE_URL", @@ -36,6 +36,7 @@ requiredFhirProperties.forEach { property -> project.extra.set(property, localProperties.getProperty(property, when { property.contains("URL") -> "https://sample.url/fhir/" property == "OPENSRP_APP_ID" -> """""""" + property == "SKIP_AUTHENTICATION" -> "false" else -> "sample_$property" } )) diff --git a/android/quest/build.gradle.kts b/android/quest/build.gradle.kts index 6baf09f5a1b..3eed9918479 100644 --- a/android/quest/build.gradle.kts +++ b/android/quest/build.gradle.kts @@ -68,7 +68,7 @@ android { versionName = BuildConfigs.versionName multiDexEnabled = true - buildConfigField("boolean", "SKIP_AUTH_CHECK", "false") + buildConfigField("boolean", "SKIP_AUTHENTICATION", "${project.extra["SKIP_AUTHENTICATION"]}") buildConfigField("String", "FHIR_BASE_URL", """"${project.extra["FHIR_BASE_URL"]}"""") buildConfigField("String", "OAUTH_BASE_URL", """"${project.extra["OAUTH_BASE_URL"]}"""") buildConfigField("String", "OAUTH_CLIENT_ID", """"${project.extra["OAUTH_CLIENT_ID"]}"""") diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingActivity.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingActivity.kt index 091114319f1..568174d170e 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingActivity.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingActivity.kt @@ -34,13 +34,10 @@ import org.smartregister.fhircore.engine.util.SharedPreferencesHelper import org.smartregister.fhircore.engine.util.extension.applyWindowInsetListener import org.smartregister.fhircore.engine.util.extension.showToast import org.smartregister.fhircore.quest.BuildConfig -import org.smartregister.fhircore.quest.ui.login.AccountAuthenticator @AndroidEntryPoint class AppSettingActivity : AppCompatActivity() { - @Inject lateinit var accountAuthenticator: AccountAuthenticator - @Inject lateinit var sharedPreferencesHelper: SharedPreferencesHelper @Inject lateinit var dispatcherProvider: DispatcherProvider @@ -70,7 +67,7 @@ class AppSettingActivity : AppCompatActivity() { onApplicationIdChanged(existingAppId) loadConfigurations(appSettingActivity) } - } else if (!BuildConfig.OPENSRP_APP_ID.isNullOrEmpty()) { + } else if (BuildConfig.OPENSRP_APP_ID.isNotEmpty()) { appSettingViewModel.onApplicationIdChanged(BuildConfig.OPENSRP_APP_ID) appSettingViewModel.fetchConfigurations(appSettingActivity) } else { diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt index 33706f11291..22530061379 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/appsetting/AppSettingViewModel.kt @@ -17,6 +17,7 @@ package org.smartregister.fhircore.quest.ui.appsetting import android.content.Context +import android.content.Intent import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -51,6 +52,7 @@ import org.smartregister.fhircore.engine.util.extension.launchActivityWithNoBack import org.smartregister.fhircore.engine.util.extension.retrieveCompositionSections import org.smartregister.fhircore.engine.util.extension.retrieveImplementationGuideDefinitionResources import org.smartregister.fhircore.quest.ui.login.LoginActivity +import org.smartregister.fhircore.quest.ui.main.AppMainActivity import retrofit2.HttpException import timber.log.Timber @@ -229,7 +231,12 @@ constructor( showProgressBar.postValue(false) if (loadConfigSuccessful) { sharedPreferencesHelper.write(SharedPreferenceKey.APP_ID.name, thisAppId) - context.getActivity()?.launchActivityWithNoBackStackHistory() + val activity = context.getActivity() + when { + org.smartregister.fhircore.quest.BuildConfig.SKIP_AUTHENTICATION -> + activity?.startActivity(Intent(context, AppMainActivity::class.java)) + else -> activity?.launchActivityWithNoBackStackHistory() + } } else { _error.postValue(context.getString(R.string.application_not_supported, thisAppId)) } @@ -288,9 +295,4 @@ constructor( } @VisibleForTesting fun isNonProxy(): Boolean = _isNonProxy - - @VisibleForTesting - fun setNonProxy(nonProxy: Boolean) { - _isNonProxy = nonProxy - } } diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/login/LoginActivity.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/login/LoginActivity.kt index ebc621174fc..3c645d33e32 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/login/LoginActivity.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/login/LoginActivity.kt @@ -22,7 +22,6 @@ import android.os.Bundle import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.annotation.VisibleForTesting -import androidx.compose.material.ExperimentalMaterialApi import androidx.core.os.bundleOf import androidx.lifecycle.viewModelScope import androidx.work.WorkManager @@ -114,7 +113,6 @@ open class LoginActivity : BaseMultiLanguageActivity() { @VisibleForTesting open fun deviceOnline() = isDeviceOnline() - @OptIn(ExperimentalMaterialApi::class) fun navigateToHome() { startActivity(Intent(this, AppMainActivity::class.java)) // Initialize P2P after login only when username is provided then finish activity diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainActivity.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainActivity.kt index 6f446cc57af..013a6844b45 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainActivity.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainActivity.kt @@ -29,7 +29,6 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels -import androidx.compose.material.ExperimentalMaterialApi import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.navigation.fragment.NavHostFragment @@ -73,7 +72,6 @@ import org.smartregister.fhircore.quest.ui.shared.models.QuestionnaireSubmission import timber.log.Timber @AndroidEntryPoint -@ExperimentalMaterialApi open class AppMainActivity : BaseMultiLanguageActivity(), QuestionnaireHandler, OnSyncListener { @Inject lateinit var syncListenerManager: SyncListenerManager @@ -134,14 +132,14 @@ open class AppMainActivity : BaseMultiLanguageActivity(), QuestionnaireHandler, lifecycleScope.launch(dispatcherProvider.main()) { val navController = (supportFragmentManager.findFragmentById(R.id.nav_host) as NavHostFragment).navController + val launcherType = + appMainViewModel.applicationConfiguration.navigationStartDestination.launcherType val graph = withContext(dispatcherProvider.io()) { navController.navInflater.inflate(R.navigation.application_nav_graph).apply { val startDestination = - when ( - appMainViewModel.applicationConfiguration.navigationStartDestination.launcherType - ) { + when (launcherType) { LauncherType.MAP -> R.id.geoWidgetLauncherFragment LauncherType.REGISTER -> R.id.registerFragment } @@ -152,7 +150,7 @@ open class AppMainActivity : BaseMultiLanguageActivity(), QuestionnaireHandler, appMainViewModel.run { navController.setGraph(graph, getStartDestinationArgs()) retrieveAppMainUiState() - withContext(dispatcherProvider.io()) { schedulePeriodicJobs(this@AppMainActivity) } + schedulePeriodicJobs(this@AppMainActivity) } setupLocationServices() diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainViewModel.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainViewModel.kt index 1ea75e601f1..37a4e2fd318 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainViewModel.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/AppMainViewModel.kt @@ -82,6 +82,7 @@ import org.smartregister.fhircore.engine.util.extension.retrieveRelatedEntitySyn import org.smartregister.fhircore.engine.util.extension.setAppLocale import org.smartregister.fhircore.engine.util.extension.showToast import org.smartregister.fhircore.engine.util.extension.tryParse +import org.smartregister.fhircore.quest.BuildConfig import org.smartregister.fhircore.quest.navigation.MainNavigationScreen import org.smartregister.fhircore.quest.navigation.NavigationArg import org.smartregister.fhircore.quest.ui.report.measure.worker.MeasureReportMonthPeriodWorker @@ -319,12 +320,6 @@ constructor( fun retrieveLastSyncTimestamp(): String? = sharedPreferencesHelper.read(SharedPreferenceKey.LAST_SYNC_TIMESTAMP.name, null) - fun schedulePeriodicSync() { - viewModelScope.launch { - syncBroadcaster.schedulePeriodicSync(applicationConfiguration.syncInterval) - } - } - fun getStartDestinationArgs(): Bundle { val startDestinationConfig = applicationConfiguration.navigationStartDestination @@ -421,27 +416,30 @@ constructor( private fun getSyncProgress(completed: Int, total: Int) = completed * 100 / if (total > 0) total else 1 - suspend fun schedulePeriodicJobs(context: Context) { - if (context.isDeviceOnline()) { - // Do not schedule sync until location selected when strategy is RelatedEntityLocation - // Use applicationConfiguration.usePractitionerAssignedLocationOnSync to identify - // if we need to trigger sync based on assigned locations or not - if (applicationConfiguration.syncStrategy.contains(SyncStrategy.RelatedEntityLocation)) { - if ( - applicationConfiguration.usePractitionerAssignedLocationOnSync || - context - .retrieveRelatedEntitySyncLocationState(MultiSelectViewAction.SYNC_DATA) - .isNotEmpty() - ) { - schedulePeriodicSync() - } - } else { - schedulePeriodicSync() - } - } else { - with(context) { - withContext(dispatcherProvider.main()) { - showToast(getString(R.string.sync_failed), Toast.LENGTH_LONG) + fun schedulePeriodicJobs(context: Context) { + viewModelScope.launch { + if (!BuildConfig.SKIP_AUTHENTICATION) { + if (context.isDeviceOnline()) { + // Do not schedule sync until location selected when strategy is RelatedEntityLocation + // Use applicationConfiguration.usePractitionerAssignedLocationOnSync to identify + // if we need to trigger sync based on assigned locations or not + when { + applicationConfiguration.syncStrategy.contains(SyncStrategy.RelatedEntityLocation) -> { + if ( + applicationConfiguration.usePractitionerAssignedLocationOnSync || + context + .retrieveRelatedEntitySyncLocationState(MultiSelectViewAction.SYNC_DATA) + .isNotEmpty() + ) { + syncBroadcaster.schedulePeriodicSync(applicationConfiguration.syncInterval) + } + } + else -> syncBroadcaster.schedulePeriodicSync(applicationConfiguration.syncInterval) + } + } else { + withContext(dispatcherProvider.main()) { + context.showToast(context.getString(R.string.sync_failed), Toast.LENGTH_LONG) + } } } } @@ -468,11 +466,13 @@ constructor( initialDelay = INITIAL_DELAY, ) - schedulePeriodically( - workId = CustomSyncWorker.WORK_ID, - repeatInterval = applicationConfiguration.syncInterval, - initialDelay = 0, - ) + if (!BuildConfig.SKIP_AUTHENTICATION) { + schedulePeriodically( + workId = CustomSyncWorker.WORK_ID, + repeatInterval = applicationConfiguration.syncInterval, + initialDelay = 0, + ) + } measureReportConfigurations.forEach { measureReportConfig -> measureReportConfig.scheduledGenerationDuration?.let { scheduledGenerationDuration -> diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/components/AppDrawer.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/components/AppDrawer.kt index 600ca523f66..aaea801c58a 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/components/AppDrawer.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/main/components/AppDrawer.kt @@ -93,6 +93,7 @@ import org.smartregister.fhircore.engine.ui.theme.SyncBarBackgroundColor import org.smartregister.fhircore.engine.ui.theme.WarningColor import org.smartregister.fhircore.engine.util.annotation.PreviewWithBackgroundExcludeGenerated import org.smartregister.fhircore.engine.util.extension.appVersion +import org.smartregister.fhircore.quest.BuildConfig import org.smartregister.fhircore.quest.R import org.smartregister.fhircore.quest.ui.main.AppMainEvent import org.smartregister.fhircore.quest.ui.main.AppMainUiState @@ -150,14 +151,16 @@ fun AppDrawer( } }, bottomBar = { // Display bottom section of the nav (sync) - NavBottomSection( - appUiState = appUiState, - appDrawerUIState = appDrawerUIState, - unSyncedResourceCount = unSyncedResourceCount, - onSideMenuClick = onSideMenuClick, - openDrawer = openDrawer, - decodeImage = decodeImage, - ) + if (!BuildConfig.SKIP_AUTHENTICATION) { + NavBottomSection( + appUiState = appUiState, + appDrawerUIState = appDrawerUIState, + unSyncedResourceCount = unSyncedResourceCount, + onSideMenuClick = onSideMenuClick, + openDrawer = openDrawer, + decodeImage = decodeImage, + ) + } }, ) { innerPadding -> Box( diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/pin/PinLoginActivity.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/pin/PinLoginActivity.kt index a8856bc61d0..24d2e2416c9 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/pin/PinLoginActivity.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/pin/PinLoginActivity.kt @@ -21,12 +21,8 @@ import android.net.Uri import android.os.Bundle import androidx.activity.compose.setContent import androidx.activity.viewModels -import androidx.compose.material.ExperimentalMaterialApi -import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import org.smartregister.fhircore.engine.p2p.dao.P2PReceiverTransferDao import org.smartregister.fhircore.engine.p2p.dao.P2PSenderTransferDao import org.smartregister.fhircore.engine.ui.base.BaseMultiLanguageActivity @@ -81,26 +77,20 @@ class PinLoginActivity : BaseMultiLanguageActivity() { setContent { AppTheme { PinLoginScreen(pinViewModel) } } } - @OptIn(ExperimentalMaterialApi::class) private fun navigateToHome() { startActivity(Intent(this, AppMainActivity::class.java)) - - lifecycleScope.launch { - // Initialize P2P only when username is provided then launch main activity - val username = secureSharedPreference.retrieveSessionUsername() - if (!username.isNullOrEmpty()) { - withContext(dispatcherProvider.main()) { - P2PLibrary.init( - P2PLibrary.Options( - context = applicationContext, - dbPassphrase = username, - username = username, - senderTransferDao = p2pSenderTransferDao, - receiverTransferDao = p2pReceiverTransferDao, - ), - ) - } - } + // Initialize P2P only when username is provided then launch main activity + val username = secureSharedPreference.retrieveSessionUsername() + if (!username.isNullOrEmpty()) { + P2PLibrary.init( + P2PLibrary.Options( + context = applicationContext, + dbPassphrase = username, + username = username, + senderTransferDao = p2pSenderTransferDao, + receiverTransferDao = p2pReceiverTransferDao, + ), + ) } } diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/register/RegisterScreen.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/register/RegisterScreen.kt index 4db108fa4f7..8911e954fe7 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/register/RegisterScreen.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/register/RegisterScreen.kt @@ -65,6 +65,7 @@ import org.smartregister.fhircore.engine.ui.components.register.LoaderDialog import org.smartregister.fhircore.engine.ui.components.register.RegisterHeader import org.smartregister.fhircore.engine.ui.theme.AppTheme import org.smartregister.fhircore.engine.util.annotation.PreviewWithBackgroundExcludeGenerated +import org.smartregister.fhircore.quest.BuildConfig import org.smartregister.fhircore.quest.event.ToolbarClickEvent import org.smartregister.fhircore.quest.ui.main.AppMainEvent import org.smartregister.fhircore.quest.ui.main.components.TopScreenSection @@ -170,7 +171,7 @@ fun RegisterScreen( }, ) { innerPadding -> Box(modifier = modifier.padding(innerPadding)) { - if (registerUiState.isFirstTimeSync) { + if (!BuildConfig.SKIP_AUTHENTICATION && registerUiState.isFirstTimeSync) { LoaderDialog( modifier = modifier.testTag(FIRST_TIME_SYNC_DIALOG), percentageProgressFlow = flowOf(appDrawerUIState.percentageProgress ?: 0), diff --git a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/usersetting/UserSettingFragment.kt b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/usersetting/UserSettingFragment.kt index ad7169aa85e..5979e69c3b4 100644 --- a/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/usersetting/UserSettingFragment.kt +++ b/android/quest/src/main/java/org/smartregister/fhircore/quest/ui/usersetting/UserSettingFragment.kt @@ -105,7 +105,8 @@ class UserSettingFragment : Fragment(), OnSyncListener { showProgressIndicatorFlow = userSettingViewModel.showProgressIndicatorFlow, dataMigrationVersion = userSettingViewModel.retrieveDataMigrationVersion(), enableManualSync = - userSettingViewModel.enableMenuOption(SettingsOptions.MANUAL_SYNC), + !org.smartregister.fhircore.quest.BuildConfig.SKIP_AUTHENTICATION && + userSettingViewModel.enableMenuOption(SettingsOptions.MANUAL_SYNC), allowSwitchingLanguages = userSettingViewModel.allowSwitchingLanguages(), showDatabaseResetConfirmation = userSettingViewModel.enableMenuOption(SettingsOptions.RESET_DATA) &&