diff --git a/app/src/main/java/foundation/e/apps/MainActivity.kt b/app/src/main/java/foundation/e/apps/MainActivity.kt index 46e48eafb2f04d1d997a04cea47872364444b279..618ce7584239e6946d11d5f774625f7e1c2969a4 100644 --- a/app/src/main/java/foundation/e/apps/MainActivity.kt +++ b/app/src/main/java/foundation/e/apps/MainActivity.kt @@ -23,6 +23,7 @@ import android.os.Build.VERSION import android.os.Build.VERSION_CODES import android.os.Bundle import android.view.View +import android.widget.Toast import android.window.OnBackInvokedDispatcher.PRIORITY_DEFAULT import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Lifecycle @@ -466,6 +467,9 @@ class MainActivity : AppCompatActivity() { }.distinctUntilChanged { old, new -> ((old.data is String) && (new.data is String) && old.data == new.data) }.collectLatest { + if (BuildConfig.DEBUG) { + Toast.makeText(this, "Refreshing token...", Toast.LENGTH_SHORT).show() + } validatedAuthObject(it) } } diff --git a/app/src/main/java/foundation/e/apps/data/application/search/SearchApiImpl.kt b/app/src/main/java/foundation/e/apps/data/application/search/SearchApiImpl.kt index bf19c7af8daf2985507964052da7b16fe270cb48..0c16bb68f3282b2a06131e2a4dff153459453a6b 100644 --- a/app/src/main/java/foundation/e/apps/data/application/search/SearchApiImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/application/search/SearchApiImpl.kt @@ -1,6 +1,5 @@ /* - * Copyright MURENA SAS 2023 - * Apps Quickly and easily install Android apps onto your device! + * Copyright (C) 2024 MURENA SAS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,6 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * */ package foundation.e.apps.data.application.search @@ -28,11 +28,11 @@ import foundation.e.apps.data.AppSourcesContainer import foundation.e.apps.data.ResultSupreme import foundation.e.apps.data.application.ApplicationDataManager import foundation.e.apps.data.application.apps.AppsApi +import foundation.e.apps.data.application.data.Application +import foundation.e.apps.data.application.data.Home import foundation.e.apps.data.application.search.SearchApi.Companion.APP_TYPE_ANY import foundation.e.apps.data.application.search.SearchApi.Companion.APP_TYPE_OPEN import foundation.e.apps.data.application.search.SearchApi.Companion.APP_TYPE_PWA -import foundation.e.apps.data.application.data.Application -import foundation.e.apps.data.application.data.Home import foundation.e.apps.data.application.utils.toApplication import foundation.e.apps.data.enums.Origin import foundation.e.apps.data.enums.ResultStatus @@ -43,7 +43,9 @@ import foundation.e.apps.ui.search.SearchResult import foundation.e.apps.utils.eventBus.AppEvent import foundation.e.apps.utils.eventBus.EventBus import kotlinx.coroutines.Deferred +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @@ -65,6 +67,11 @@ class SearchApiImpl @Inject constructor( companion object { private const val KEYWORD_TEST_SEARCH = "facebook" + + private val DUMMY_SEARCH_EXPECTED_APPS = listOf( + "Facebook" to "com.facebook.katana", + "Messenger" to "com.facebook.orca" + ) } override fun getSelectedAppTypes(): List { @@ -327,6 +334,8 @@ class SearchApiImpl @Inject constructor( nextPageSubBundle: Set? ): GplaySearchResult { return handleNetworkResult { + coroutineScope { launch(Dispatchers.IO) { doDummySearch() } } + val searchResults = appSources.gplayRepo.getSearchResult(query, nextPageSubBundle?.toMutableSet()) @@ -339,8 +348,6 @@ class SearchApiImpl @Inject constructor( val fusedAppList = replaceWithFDroid(searchResults.first).toMutableList() - handleLimitedResult(fusedAppList) - if (searchResults.second.isNotEmpty()) { fusedAppList.add(Application(isPlaceHolder = true)) } @@ -349,15 +356,25 @@ class SearchApiImpl @Inject constructor( } } - private suspend fun handleLimitedResult(appList: List?) { - if (appList.isNullOrEmpty()) { - // Call search api with a common keyword (ex: facebook) - // to ensure Gplay is returning empty as search result for other keywords as well - val searchResult = appSources.gplayRepo.getSearchResult(KEYWORD_TEST_SEARCH, null) - if (searchResult.first.isEmpty()) { - Timber.w("Limited result for search is found...") - refreshToken() - } + // Initiate a dummy search to ensure Google Play returns enough results for the search query + private suspend fun doDummySearch() { + val (searchedApps, _) = appSources.gplayRepo.getSearchResult(KEYWORD_TEST_SEARCH, null) + + if (searchedApps.isEmpty()) { + Timber.d("Search returned empty results, refreshing token...") + refreshToken() + return + } + + val dummySearchPackageNames = DUMMY_SEARCH_EXPECTED_APPS.map { it.second } + val searchedAppsPackageNames = searchedApps.map { it.packageName } + + val isSearchContainingResults = searchedAppsPackageNames.containsAll(dummySearchPackageNames) + + if (!isSearchContainingResults) { + Timber.d("Search didn't return enough results, refreshing token...") + refreshToken() + return } } diff --git a/app/src/main/java/foundation/e/apps/data/playstore/PlayStoreRepositoryImpl.kt b/app/src/main/java/foundation/e/apps/data/playstore/PlayStoreRepositoryImpl.kt index 5a6bf1e6788ad493abe61d33bafdb6c447b3cbc9..9ea9db7b9a003e58e63ced57f42345d2b4532e54 100644 --- a/app/src/main/java/foundation/e/apps/data/playstore/PlayStoreRepositoryImpl.kt +++ b/app/src/main/java/foundation/e/apps/data/playstore/PlayStoreRepositoryImpl.kt @@ -79,7 +79,7 @@ class PlayStoreRepositoryImpl @Inject constructor( query: String, subBundle: MutableSet? ): Pair, MutableSet> { - var authData = authenticatorRepository.gplayAuth!! + val authData = authenticatorRepository.gplayAuth!! val searchHelper = SearchHelper(authData).using(gPlayHttpClient) Timber.d("Fetching search result for $query, subBundle: $subBundle") @@ -87,18 +87,19 @@ class PlayStoreRepositoryImpl @Inject constructor( subBundle?.let { val searchResult = searchHelper.next(it) Timber.d("fetching next page search data...") - return getSearchResultPair(searchResult) + return getSearchResultPair(searchResult, query) } val searchResult = searchHelper.searchResults(query) - return getSearchResultPair(searchResult) + return getSearchResultPair(searchResult, query) } private fun getSearchResultPair( - searchBundle: SearchBundle + searchBundle: SearchBundle, + query: String ): Pair, MutableSet> { val apps = searchBundle.appList - Timber.d("Search result is found: ${apps.size}") + Timber.d("Found ${apps.size} apps for query, $query") return Pair(apps, searchBundle.subBundles) } diff --git a/app/src/main/java/foundation/e/apps/di/network/InterceptorModule.kt b/app/src/main/java/foundation/e/apps/di/network/InterceptorModule.kt index 476e5f7d8d3612043a94dca4a25cb6bfe78f3370..817c837893cb29b2ee25df757b22e3c46015de8c 100644 --- a/app/src/main/java/foundation/e/apps/di/network/InterceptorModule.kt +++ b/app/src/main/java/foundation/e/apps/di/network/InterceptorModule.kt @@ -62,7 +62,7 @@ class InterceptorModule { fun provideLoggingInterceptor(): HttpLoggingInterceptor { return HttpLoggingInterceptor().apply { level = when { - BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY + BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.HEADERS else -> HttpLoggingInterceptor.Level.NONE } }