Loading app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +2 −13 Original line number Diff line number Diff line Loading @@ -109,13 +109,6 @@ class FusedAPIImpl @Inject constructor( return true } fun isCategoriesEmpty(fusedCategories: List<FusedCategory>): Boolean { fusedCategories.forEach { if (it.title.isNotEmpty()) return false } return true } fun getApplicationCategoryPreference(): String { return preferenceManagerModule.preferredApplicationType() } Loading Loading @@ -177,11 +170,7 @@ class FusedAPIImpl @Inject constructor( setHomeErrorMessage(apiStatus, source) scope.emit( ResultSupreme.create(apiStatus, priorList.toList()).apply { otherPayload = source.name } ) scope.emit(ResultSupreme.create(apiStatus, priorList)) } private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) { Loading Loading @@ -1345,7 +1334,7 @@ class FusedAPIImpl @Inject constructor( updateFilterLevel(authData) } } list.add(FusedHome(it.key, result, source = APP_TYPE_ANY)) list.add(FusedHome(it.key, result)) } return list } Loading app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +0 −4 Original line number Diff line number Diff line Loading @@ -86,10 +86,6 @@ class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedAPII return fusedAPIImpl.isFusedHomesEmpty(fusedHomes) } fun isCategoriesEmpty(fusedCategories: List<FusedCategory>): Boolean { return fusedAPIImpl.isCategoriesEmpty(fusedCategories) } fun getApplicationCategoryPreference(): String { return fusedAPIImpl.getApplicationCategoryPreference() } Loading app/src/main/java/foundation/e/apps/categories/CategoriesViewModel.kt +14 −25 Original line number Diff line number Diff line Loading @@ -26,12 +26,9 @@ import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.api.fused.FusedAPIRepository import foundation.e.apps.api.fused.data.FusedCategory import foundation.e.apps.login.AuthObject import foundation.e.apps.utils.enums.AppTag import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.enums.User import foundation.e.apps.utils.exceptions.CleanApkException import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.exceptions.GPlayLoginException import foundation.e.apps.utils.parentFragment.LoadingViewModel import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -52,33 +49,25 @@ class CategoriesViewModel @Inject constructor( super.onLoadData(authObjectList, { successAuthList, _ -> successAuthList.find { it is AuthObject.GPlayAuth }?.run { getCategoriesList(type, result.data!! as AuthData, this.user) getCategoriesList(type, result.data!! as AuthData) return@onLoadData } successAuthList.find { it is AuthObject.CleanApk }?.run { getCategoriesList(type, AuthData("", ""), this.user) getCategoriesList(type, AuthData("", "")) return@onLoadData } }, retryBlock) } fun getCategoriesList(type: Category.Type, authData: AuthData, user: User) { fun getCategoriesList(type: Category.Type, authData: AuthData) { viewModelScope.launch { val categoriesData = fusedAPIRepository.getCategoriesList(type, authData) categoriesList.postValue(categoriesData) val status = categoriesData.third val categoriesList = categoriesData.first if (status == ResultStatus.OK) { if (categoriesList.all { it.tag is AppTag.GPlay } && isCategoriesEmpty(categoriesList)) { exceptionsList.add(GPlayLoginException(false, "Received empty Categories", user)) } return@launch } if (status != ResultStatus.OK) { val exception = if (authData.aasToken.isNotBlank() || authData.authToken.isNotBlank()) GPlayException( Loading @@ -91,11 +80,11 @@ class CategoriesViewModel @Inject constructor( ) exceptionsList.add(exception) exceptionsLiveData.postValue(exceptionsList) exceptionsLiveData.postValue(exceptionsList)} } } fun isCategoriesEmpty(fusedCategories: List<FusedCategory>): Boolean { return fusedAPIRepository.isCategoriesEmpty(fusedCategories) fun isCategoriesEmpty(): Boolean { return categoriesList.value?.first?.isEmpty() ?: true } } app/src/main/java/foundation/e/apps/home/HomeViewModel.kt +5 −17 Original line number Diff line number Diff line Loading @@ -28,11 +28,8 @@ import foundation.e.apps.api.fused.FusedAPIRepository import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.api.fused.data.FusedHome import foundation.e.apps.login.AuthObject import foundation.e.apps.utils.enums.Source import foundation.e.apps.utils.enums.User import foundation.e.apps.utils.exceptions.CleanApkException import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.exceptions.GPlayLoginException import foundation.e.apps.utils.parentFragment.LoadingViewModel import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -58,12 +55,12 @@ class HomeViewModel @Inject constructor( super.onLoadData(authObjectList, { successAuthList, _ -> successAuthList.find { it is AuthObject.GPlayAuth }?.run { getHomeScreenData(result.data!! as AuthData, this.user, lifecycleOwner) getHomeScreenData(result.data!! as AuthData, lifecycleOwner) return@onLoadData } successAuthList.find { it is AuthObject.CleanApk }?.run { getHomeScreenData(AuthData("", ""), this.user, lifecycleOwner) getHomeScreenData(AuthData("", ""), lifecycleOwner) return@onLoadData } }, retryBlock) Loading @@ -71,22 +68,13 @@ class HomeViewModel @Inject constructor( fun getHomeScreenData( authData: AuthData, user: User, lifecycleOwner: LifecycleOwner, ) { viewModelScope.launch { fusedAPIRepository.getHomeScreenData(authData).observe(lifecycleOwner) { homeScreenData.postValue(it) val homeList = it.data ?: emptyList() val source = it.otherPayload?.toString() ?: "" if (it.isSuccess()) { if (homeList.all { source == Source.GPLAY.name } && isFusedHomesEmpty(homeList)) { exceptionsList.add(GPlayLoginException(false, "Received empty Home", user)) } return@observe } if (it.isSuccess()) return@observe val exception = if (authData.aasToken.isNotBlank() || authData.authToken.isNotBlank()) Loading @@ -109,8 +97,8 @@ class HomeViewModel @Inject constructor( return fusedAPIRepository.getApplicationCategoryPreference() } fun isFusedHomesEmpty(fusedHomes: List<FusedHome>): Boolean { return fusedHomes.let { fun isFusedHomesEmpty(): Boolean { return homeScreenData.value?.data?.let { fusedAPIRepository.isFusedHomesEmpty(it) } ?: true } Loading app/src/main/java/foundation/e/apps/login/LoginSourceGPlay.kt +57 −8 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import foundation.e.apps.login.api.GPlayLoginInterface import foundation.e.apps.login.api.GoogleLoginApi import foundation.e.apps.login.api.LoginApiRepository import foundation.e.apps.utils.enums.User import foundation.e.apps.utils.exceptions.GPlayValidationException import java.util.Locale import javax.inject.Inject import javax.inject.Singleton Loading Loading @@ -74,15 +75,23 @@ class LoginSourceGPlay @Inject constructor( */ override suspend fun getAuthObject(): AuthObject.GPlayAuth { val savedAuth = getSavedAuthData() return if (savedAuth != null) { AuthObject.GPlayAuth(ResultSupreme.Success(savedAuth), user) } else { val authData = ( savedAuth ?: run { // if no saved data, then generate new auth data. generateAuthData().let { if (it.isSuccess()) { saveAuthData(it.data!!) AuthObject.GPlayAuth(it, user) } else AuthObject.GPlayAuth(it, user) if (it.isSuccess()) it.data!! else return AuthObject.GPlayAuth(it, user) } } ) // validate authData and save it if nothing is saved (first time use.) validateAuthData(authData).run { if (isSuccess() && savedAuth == null) { saveAuthData(authData) } return AuthObject.GPlayAuth(this, user) } } Loading Loading @@ -195,4 +204,44 @@ class LoginSourceGPlay @Inject constructor( else this } } /** * Check if a given [AuthData] from Google login or Anonymous login is valid or not. * If valid, return the AuthData wrapped in [ResultSupreme], else return null, * with error message. */ private suspend fun validateAuthData( authData: AuthData, ): ResultSupreme<AuthData?> { val formattedAuthData = formattedAuthData(authData) formattedAuthData.locale = locale val validityResponse = loginApiRepository.login(formattedAuthData) /* * Send the email as payload. This is sent to ecloud in case of failure. * See MainActivityViewModel.uploadFaultyTokenToEcloud. */ validityResponse.otherPayload = formattedAuthData.email val playResponse = validityResponse.data return if (validityResponse.isSuccess() && playResponse?.code == 200 && playResponse.isSuccessful) { ResultSupreme.Success(formattedAuthData) } else { val message = "Validating AuthData failed.\n" + "Network code: ${playResponse?.code}\n" + "Success: ${playResponse?.isSuccessful}" + playResponse?.errorString?.run { if (isNotBlank()) "\nError message: $this" else "" } ResultSupreme.Error( message, GPlayValidationException(message, user, playResponse?.code ?: -1) ) } } } Loading
app/src/main/java/foundation/e/apps/api/fused/FusedAPIImpl.kt +2 −13 Original line number Diff line number Diff line Loading @@ -109,13 +109,6 @@ class FusedAPIImpl @Inject constructor( return true } fun isCategoriesEmpty(fusedCategories: List<FusedCategory>): Boolean { fusedCategories.forEach { if (it.title.isNotEmpty()) return false } return true } fun getApplicationCategoryPreference(): String { return preferenceManagerModule.preferredApplicationType() } Loading Loading @@ -177,11 +170,7 @@ class FusedAPIImpl @Inject constructor( setHomeErrorMessage(apiStatus, source) scope.emit( ResultSupreme.create(apiStatus, priorList.toList()).apply { otherPayload = source.name } ) scope.emit(ResultSupreme.create(apiStatus, priorList)) } private fun setHomeErrorMessage(apiStatus: ResultStatus, source: Source) { Loading Loading @@ -1345,7 +1334,7 @@ class FusedAPIImpl @Inject constructor( updateFilterLevel(authData) } } list.add(FusedHome(it.key, result, source = APP_TYPE_ANY)) list.add(FusedHome(it.key, result)) } return list } Loading
app/src/main/java/foundation/e/apps/api/fused/FusedAPIRepository.kt +0 −4 Original line number Diff line number Diff line Loading @@ -86,10 +86,6 @@ class FusedAPIRepository @Inject constructor(private val fusedAPIImpl: FusedAPII return fusedAPIImpl.isFusedHomesEmpty(fusedHomes) } fun isCategoriesEmpty(fusedCategories: List<FusedCategory>): Boolean { return fusedAPIImpl.isCategoriesEmpty(fusedCategories) } fun getApplicationCategoryPreference(): String { return fusedAPIImpl.getApplicationCategoryPreference() } Loading
app/src/main/java/foundation/e/apps/categories/CategoriesViewModel.kt +14 −25 Original line number Diff line number Diff line Loading @@ -26,12 +26,9 @@ import dagger.hilt.android.lifecycle.HiltViewModel import foundation.e.apps.api.fused.FusedAPIRepository import foundation.e.apps.api.fused.data.FusedCategory import foundation.e.apps.login.AuthObject import foundation.e.apps.utils.enums.AppTag import foundation.e.apps.utils.enums.ResultStatus import foundation.e.apps.utils.enums.User import foundation.e.apps.utils.exceptions.CleanApkException import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.exceptions.GPlayLoginException import foundation.e.apps.utils.parentFragment.LoadingViewModel import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -52,33 +49,25 @@ class CategoriesViewModel @Inject constructor( super.onLoadData(authObjectList, { successAuthList, _ -> successAuthList.find { it is AuthObject.GPlayAuth }?.run { getCategoriesList(type, result.data!! as AuthData, this.user) getCategoriesList(type, result.data!! as AuthData) return@onLoadData } successAuthList.find { it is AuthObject.CleanApk }?.run { getCategoriesList(type, AuthData("", ""), this.user) getCategoriesList(type, AuthData("", "")) return@onLoadData } }, retryBlock) } fun getCategoriesList(type: Category.Type, authData: AuthData, user: User) { fun getCategoriesList(type: Category.Type, authData: AuthData) { viewModelScope.launch { val categoriesData = fusedAPIRepository.getCategoriesList(type, authData) categoriesList.postValue(categoriesData) val status = categoriesData.third val categoriesList = categoriesData.first if (status == ResultStatus.OK) { if (categoriesList.all { it.tag is AppTag.GPlay } && isCategoriesEmpty(categoriesList)) { exceptionsList.add(GPlayLoginException(false, "Received empty Categories", user)) } return@launch } if (status != ResultStatus.OK) { val exception = if (authData.aasToken.isNotBlank() || authData.authToken.isNotBlank()) GPlayException( Loading @@ -91,11 +80,11 @@ class CategoriesViewModel @Inject constructor( ) exceptionsList.add(exception) exceptionsLiveData.postValue(exceptionsList) exceptionsLiveData.postValue(exceptionsList)} } } fun isCategoriesEmpty(fusedCategories: List<FusedCategory>): Boolean { return fusedAPIRepository.isCategoriesEmpty(fusedCategories) fun isCategoriesEmpty(): Boolean { return categoriesList.value?.first?.isEmpty() ?: true } }
app/src/main/java/foundation/e/apps/home/HomeViewModel.kt +5 −17 Original line number Diff line number Diff line Loading @@ -28,11 +28,8 @@ import foundation.e.apps.api.fused.FusedAPIRepository import foundation.e.apps.api.fused.data.FusedApp import foundation.e.apps.api.fused.data.FusedHome import foundation.e.apps.login.AuthObject import foundation.e.apps.utils.enums.Source import foundation.e.apps.utils.enums.User import foundation.e.apps.utils.exceptions.CleanApkException import foundation.e.apps.utils.exceptions.GPlayException import foundation.e.apps.utils.exceptions.GPlayLoginException import foundation.e.apps.utils.parentFragment.LoadingViewModel import kotlinx.coroutines.launch import javax.inject.Inject Loading @@ -58,12 +55,12 @@ class HomeViewModel @Inject constructor( super.onLoadData(authObjectList, { successAuthList, _ -> successAuthList.find { it is AuthObject.GPlayAuth }?.run { getHomeScreenData(result.data!! as AuthData, this.user, lifecycleOwner) getHomeScreenData(result.data!! as AuthData, lifecycleOwner) return@onLoadData } successAuthList.find { it is AuthObject.CleanApk }?.run { getHomeScreenData(AuthData("", ""), this.user, lifecycleOwner) getHomeScreenData(AuthData("", ""), lifecycleOwner) return@onLoadData } }, retryBlock) Loading @@ -71,22 +68,13 @@ class HomeViewModel @Inject constructor( fun getHomeScreenData( authData: AuthData, user: User, lifecycleOwner: LifecycleOwner, ) { viewModelScope.launch { fusedAPIRepository.getHomeScreenData(authData).observe(lifecycleOwner) { homeScreenData.postValue(it) val homeList = it.data ?: emptyList() val source = it.otherPayload?.toString() ?: "" if (it.isSuccess()) { if (homeList.all { source == Source.GPLAY.name } && isFusedHomesEmpty(homeList)) { exceptionsList.add(GPlayLoginException(false, "Received empty Home", user)) } return@observe } if (it.isSuccess()) return@observe val exception = if (authData.aasToken.isNotBlank() || authData.authToken.isNotBlank()) Loading @@ -109,8 +97,8 @@ class HomeViewModel @Inject constructor( return fusedAPIRepository.getApplicationCategoryPreference() } fun isFusedHomesEmpty(fusedHomes: List<FusedHome>): Boolean { return fusedHomes.let { fun isFusedHomesEmpty(): Boolean { return homeScreenData.value?.data?.let { fusedAPIRepository.isFusedHomesEmpty(it) } ?: true } Loading
app/src/main/java/foundation/e/apps/login/LoginSourceGPlay.kt +57 −8 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import foundation.e.apps.login.api.GPlayLoginInterface import foundation.e.apps.login.api.GoogleLoginApi import foundation.e.apps.login.api.LoginApiRepository import foundation.e.apps.utils.enums.User import foundation.e.apps.utils.exceptions.GPlayValidationException import java.util.Locale import javax.inject.Inject import javax.inject.Singleton Loading Loading @@ -74,15 +75,23 @@ class LoginSourceGPlay @Inject constructor( */ override suspend fun getAuthObject(): AuthObject.GPlayAuth { val savedAuth = getSavedAuthData() return if (savedAuth != null) { AuthObject.GPlayAuth(ResultSupreme.Success(savedAuth), user) } else { val authData = ( savedAuth ?: run { // if no saved data, then generate new auth data. generateAuthData().let { if (it.isSuccess()) { saveAuthData(it.data!!) AuthObject.GPlayAuth(it, user) } else AuthObject.GPlayAuth(it, user) if (it.isSuccess()) it.data!! else return AuthObject.GPlayAuth(it, user) } } ) // validate authData and save it if nothing is saved (first time use.) validateAuthData(authData).run { if (isSuccess() && savedAuth == null) { saveAuthData(authData) } return AuthObject.GPlayAuth(this, user) } } Loading Loading @@ -195,4 +204,44 @@ class LoginSourceGPlay @Inject constructor( else this } } /** * Check if a given [AuthData] from Google login or Anonymous login is valid or not. * If valid, return the AuthData wrapped in [ResultSupreme], else return null, * with error message. */ private suspend fun validateAuthData( authData: AuthData, ): ResultSupreme<AuthData?> { val formattedAuthData = formattedAuthData(authData) formattedAuthData.locale = locale val validityResponse = loginApiRepository.login(formattedAuthData) /* * Send the email as payload. This is sent to ecloud in case of failure. * See MainActivityViewModel.uploadFaultyTokenToEcloud. */ validityResponse.otherPayload = formattedAuthData.email val playResponse = validityResponse.data return if (validityResponse.isSuccess() && playResponse?.code == 200 && playResponse.isSuccessful) { ResultSupreme.Success(formattedAuthData) } else { val message = "Validating AuthData failed.\n" + "Network code: ${playResponse?.code}\n" + "Success: ${playResponse?.isSuccessful}" + playResponse?.errorString?.run { if (isNotBlank()) "\nError message: $this" else "" } ResultSupreme.Error( message, GPlayValidationException(message, user, playResponse?.code ?: -1) ) } } }