From dffcb9c9f57e614a07b352f120f06b53903d2d57 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 04:40:47 +0530 Subject: [PATCH 01/20] introduce antifeatures --- .../foundation/e/apps/data/application/data/Application.kt | 4 +++- .../java/foundation/e/apps/data/install/models/AppInstall.kt | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/data/application/data/Application.kt b/app/src/main/java/foundation/e/apps/data/application/data/Application.kt index 98d8d56c9..2ff78b947 100644 --- a/app/src/main/java/foundation/e/apps/data/application/data/Application.kt +++ b/app/src/main/java/foundation/e/apps/data/application/data/Application.kt @@ -102,7 +102,9 @@ data class Application( var isGplayReplaced: Boolean = false, @SerializedName(value = "on_fdroid") val isFDroidApp: Boolean = false, - var contentRating: ContentRating = ContentRating() + var contentRating: ContentRating = ContentRating(), + @SerializedName(value = "antifeatures") + val antiFeatures: List> = emptyList(), ) { fun updateType() { this.type = if (this.is_pwa) PWA else NATIVE diff --git a/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt b/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt index 28f92b4d6..71ca2ffef 100644 --- a/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt +++ b/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt @@ -40,6 +40,9 @@ data class AppInstall( @Ignore var contentRating: ContentRating = ContentRating() + @Ignore + var antiFeatures: List> = emptyList() + fun isAppInstalling() = installingStatusList.contains(status) fun isAwaiting() = status == Status.AWAITING -- GitLab From 6f351af04fe5ca6141d9d49d748ce98df2335300 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 04:41:58 +0530 Subject: [PATCH 02/20] check existence of NSFW antifeature --- .../apps/domain/ValidateAppAgeLimitUseCase.kt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index c8797ecda..5b91c4717 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -19,11 +19,12 @@ package foundation.e.apps.domain import foundation.e.apps.data.ResultSupreme -import foundation.e.apps.data.application.apps.AppsApi import foundation.e.apps.data.blockedApps.Age import foundation.e.apps.data.blockedApps.ContentRatingGroup import foundation.e.apps.data.blockedApps.ContentRatingsRepository import foundation.e.apps.data.blockedApps.ParentalControlRepository +import foundation.e.apps.data.enums.Origin +import foundation.e.apps.data.enums.Type import foundation.e.apps.data.install.models.AppInstall import timber.log.Timber import javax.inject.Inject @@ -33,16 +34,31 @@ class ValidateAppAgeLimitUseCase @Inject constructor( private val parentalControlRepository: ParentalControlRepository, ) { + companion object { + private const val KEY_ANTI_FEATURES_NSFW = "NSFW" + } + suspend operator fun invoke(app: AppInstall): ResultSupreme { val ageGroup = parentalControlRepository.getSelectedAgeGroup() return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) + isFDroidApp(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) hasNoContentRating(app) -> ResultSupreme.Error(data = false) else -> validateAgeLimit(ageGroup, app) } } + private fun isFDroidApp(app: AppInstall): Boolean { + return app.origin == Origin.CLEANAPK && app.type == Type.NATIVE + } + + private fun isNsfwFDroidApp(app: AppInstall): Boolean { + return app.antiFeatures.any { + antiFeature -> antiFeature.containsKey(KEY_ANTI_FEATURES_NSFW) + } + } + private fun validateAgeLimit( ageGroup: Age, app: AppInstall -- GitLab From 5a0f8e01807fe18483539501b66bd7bdb291c088 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 04:45:24 +0530 Subject: [PATCH 03/20] add NSFW apps in blocklist from contentprovider --- .../e/apps/provider/AgeRatingProvider.kt | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt index 57164db09..6914a74c6 100644 --- a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +++ b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt @@ -35,8 +35,10 @@ import foundation.e.apps.contract.ParentalControlContract.COLUMN_PACKAGE_NAME import foundation.e.apps.contract.ParentalControlContract.PATH_BLOCKLIST import foundation.e.apps.contract.ParentalControlContract.PATH_LOGIN_TYPE import foundation.e.apps.contract.ParentalControlContract.getAppLoungeProviderAuthority +import foundation.e.apps.data.application.apps.AppsApi import foundation.e.apps.data.blockedApps.ContentRatingsRepository import foundation.e.apps.data.enums.Origin +import foundation.e.apps.data.enums.Type import foundation.e.apps.data.install.models.AppInstall import foundation.e.apps.data.login.AuthenticatorRepository import foundation.e.apps.data.preference.DataStoreManager @@ -59,6 +61,7 @@ class AgeRatingProvider : ContentProvider() { fun provideContentRatingsRepository(): ContentRatingsRepository fun provideValidateAppAgeLimitUseCase(): ValidateAppAgeLimitUseCase fun provideDataStoreManager(): DataStoreManager + fun provideAppsApi(): AppsApi } private lateinit var authenticatorRepository: AuthenticatorRepository @@ -66,6 +69,7 @@ class AgeRatingProvider : ContentProvider() { private lateinit var contentRatingsRepository: ContentRatingsRepository private lateinit var validateAppAgeLimitUseCase: ValidateAppAgeLimitUseCase private lateinit var dataStoreManager: DataStoreManager + private lateinit var appsApi: AppsApi private enum class UriCode(val code: Int) { LoginType(1), @@ -151,14 +155,35 @@ class AgeRatingProvider : ContentProvider() { return validateResult.data ?: false } + private suspend fun getNSFWValidity(packageName: String): Boolean { + val cleanapkApp = appsApi.getCleanapkAppDetails(packageName).first + val fakeAppInstall = AppInstall( + packageName = packageName, + origin = Origin.CLEANAPK, + type = Type.NATIVE, + ) + fakeAppInstall.antiFeatures = cleanapkApp.antiFeatures + val validateResult = validateAppAgeLimitUseCase(fakeAppInstall) + return validateResult.data ?: false + } + + private suspend fun shouldAllow(packageName: String): Boolean { + return when { + !getNSFWValidity(packageName) -> false + !getAppAgeValidity(packageName) -> false + else -> true + } + } + private suspend fun compileAppBlockList( cursor: MatrixCursor, packageNames: List, ) { withContext(IO) { + Timber.d("Start blocklist for ${packageNames.size} apps.") val validityList = packageNames.map { packageName -> async { - getAppAgeValidity(packageName) + shouldAllow(packageName) } }.awaitAll() validityList.forEachIndexed { index: Int, isValid: Boolean? -> @@ -167,6 +192,7 @@ class AgeRatingProvider : ContentProvider() { cursor.addRow(arrayOf(packageNames[index])) } } + Timber.d("Finished compiling blocklist") } } @@ -180,6 +206,7 @@ class AgeRatingProvider : ContentProvider() { contentRatingsRepository = hiltEntryPoint.provideContentRatingsRepository() validateAppAgeLimitUseCase = hiltEntryPoint.provideValidateAppAgeLimitUseCase() dataStoreManager = hiltEntryPoint.provideDataStoreManager() + appsApi = hiltEntryPoint.provideAppsApi() return true } -- GitLab From 35c904b72b363b7433a3615cb3cc296b708e75bb Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 04:47:05 +0530 Subject: [PATCH 04/20] logging while sending login broadcast --- app/src/main/java/foundation/e/apps/MainActivity.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/MainActivity.kt b/app/src/main/java/foundation/e/apps/MainActivity.kt index 88496dfac..cedbf9c84 100644 --- a/app/src/main/java/foundation/e/apps/MainActivity.kt +++ b/app/src/main/java/foundation/e/apps/MainActivity.kt @@ -372,9 +372,11 @@ class MainActivity : AppCompatActivity() { } private fun broadcastGPlayLogin() { + val user = viewModel.getUser().name + Timber.d("Sending broadcast with login type - $user") val intent = Intent(Constants.ACTION_PARENTAL_CONTROL_APP_LOUNGE_LOGIN).apply { setPackage(BuildConfig.PACKAGE_NAME_PARENTAL_CONTROL) - putExtra(COLUMN_LOGIN_TYPE, viewModel.getUser().name) + putExtra(COLUMN_LOGIN_TYPE, user) } sendBroadcast(intent) } -- GitLab From d7e0196ac6682c0b13b468aa6a2b572aca534358 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 05:59:06 +0530 Subject: [PATCH 05/20] set up fdroid monitor API --- .../e/apps/data/ageRating/FDroidMonitorApi.kt | 34 ++++++++++++++++++ .../apps/data/ageRating/FDroidMonitorData.kt | 36 +++++++++++++++++++ .../foundation/e/apps/di/AgeRatingModule.kt | 12 +++++++ 3 files changed, 82 insertions(+) create mode 100644 app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt create mode 100644 app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorData.kt diff --git a/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt b/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt new file mode 100644 index 000000000..099bab95f --- /dev/null +++ b/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt @@ -0,0 +1,34 @@ +/* + * Copyright MURENA SAS 2024 + * Apps Quickly and easily install Android apps onto your device! + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package foundation.e.apps.data.ageRating + +import retrofit2.Response +import retrofit2.http.GET + +interface FDroidMonitorApi { + + companion object { + const val BASE_URL = "https://f-droid.org/repo/status/" + } + + @GET("update.json") + suspend fun getMonitorData(): Response + +} diff --git a/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorData.kt b/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorData.kt new file mode 100644 index 000000000..762e60213 --- /dev/null +++ b/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorData.kt @@ -0,0 +1,36 @@ +/* + * Copyright MURENA SAS 2024 + * Apps Quickly and easily install Android apps onto your device! + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package foundation.e.apps.data.ageRating + +import com.squareup.moshi.Json + +data class FDroidMonitorData( + val antiFeatures: AntiFeatures +) { + fun getNSFWApps() = antiFeatures.nsfw.apps +} + +data class AntiFeatures( + @Json(name = "NSFW") val nsfw: NSFW +) + +data class NSFW( + val apps: List +) diff --git a/app/src/main/java/foundation/e/apps/di/AgeRatingModule.kt b/app/src/main/java/foundation/e/apps/di/AgeRatingModule.kt index 1cb262678..b47981ec9 100644 --- a/app/src/main/java/foundation/e/apps/di/AgeRatingModule.kt +++ b/app/src/main/java/foundation/e/apps/di/AgeRatingModule.kt @@ -25,6 +25,7 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.data.ageRating.AgeGroupApi +import foundation.e.apps.data.ageRating.FDroidMonitorApi import javax.inject.Singleton import okhttp3.OkHttpClient import retrofit2.Retrofit @@ -44,4 +45,15 @@ object AgeRatingModule { .build() .create(AgeGroupApi::class.java) } + + @Singleton + @Provides + fun provideFDroidMonitorApi(okHttpClient: OkHttpClient, moshi: Moshi): FDroidMonitorApi { + return Retrofit.Builder() + .baseUrl(FDroidMonitorApi.BASE_URL) + .client(okHttpClient) + .addConverterFactory(MoshiConverterFactory.create(moshi)) + .build() + .create(FDroidMonitorApi::class.java) + } } -- GitLab From 0f8a63f955a0638a70b6e48e4ba0d6c0174d62e0 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 05:59:56 +0530 Subject: [PATCH 06/20] Fetch NSFW info from FDroid monitor --- .../apps/data/blockedApps/ContentRatingsRepository.kt | 10 ++++++++++ .../java/foundation/e/apps/ui/MainActivityViewModel.kt | 1 + 2 files changed, 11 insertions(+) diff --git a/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt b/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt index 595904bbe..de7637613 100644 --- a/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt +++ b/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt @@ -22,6 +22,7 @@ package foundation.e.apps.data.blockedApps import com.aurora.gplayapi.data.models.ContentRating import com.aurora.gplayapi.helpers.ContentRatingHelper import foundation.e.apps.data.ageRating.AgeGroupApi +import foundation.e.apps.data.ageRating.FDroidMonitorApi import foundation.e.apps.data.handleNetworkResult import foundation.e.apps.data.login.AuthenticatorRepository import javax.inject.Inject @@ -30,6 +31,7 @@ import javax.inject.Singleton @Singleton class ContentRatingsRepository @Inject constructor( private val ageGroupApi: AgeGroupApi, + private val fDroidMonitorApi: FDroidMonitorApi, private val authenticatorRepository: AuthenticatorRepository, ) { @@ -37,6 +39,9 @@ class ContentRatingsRepository @Inject constructor( val contentRatingGroups: List get() = _contentRatingGroups + var fDroidNSFWApps = listOf() + private set + suspend fun fetchContentRatingData() { val response = ageGroupApi.getDefinedAgeGroups() if (response.isSuccessful) { @@ -44,6 +49,11 @@ class ContentRatingsRepository @Inject constructor( } } + suspend fun fetchNSFWApps() { + val fDroidMonitorData = fDroidMonitorApi.getMonitorData() + fDroidNSFWApps = fDroidMonitorData.body()?.getNSFWApps() ?: emptyList() + } + suspend fun getEnglishContentRating(packageName: String): ContentRating? { val authData = authenticatorRepository.gplayAuth ?: return null val contentRatingHelper = ContentRatingHelper(authData) diff --git a/app/src/main/java/foundation/e/apps/ui/MainActivityViewModel.kt b/app/src/main/java/foundation/e/apps/ui/MainActivityViewModel.kt index 4787b8e91..18a1671a9 100644 --- a/app/src/main/java/foundation/e/apps/ui/MainActivityViewModel.kt +++ b/app/src/main/java/foundation/e/apps/ui/MainActivityViewModel.kt @@ -240,6 +240,7 @@ class MainActivityViewModel @Inject constructor( fun updateContentRatings() { viewModelScope.launch { + contentRatingsRepository.fetchNSFWApps() contentRatingsRepository.fetchContentRatingData() } } -- GitLab From 81ca3cf7a3eede9e4be4c36b93c37cbf11f08ea6 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 06:11:47 +0530 Subject: [PATCH 07/20] use NSFW data from fdroid to validate apps --- .../e/apps/domain/ValidateAppAgeLimitUseCase.kt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index 5b91c4717..7dcf00519 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -43,20 +43,14 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) - isFDroidApp(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) + isNsfwFDroidApp(app) -> ResultSupreme.Success(data = false) hasNoContentRating(app) -> ResultSupreme.Error(data = false) else -> validateAgeLimit(ageGroup, app) } } - private fun isFDroidApp(app: AppInstall): Boolean { - return app.origin == Origin.CLEANAPK && app.type == Type.NATIVE - } - private fun isNsfwFDroidApp(app: AppInstall): Boolean { - return app.antiFeatures.any { - antiFeature -> antiFeature.containsKey(KEY_ANTI_FEATURES_NSFW) - } + return app.packageName in contentRatingRepository.fDroidNSFWApps } private fun validateAgeLimit( -- GitLab From bcad99e39fa53267aff76d0362904756e53f42d6 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 06:20:02 +0530 Subject: [PATCH 08/20] use fdroid monitor in AgeRatingProvider --- .../e/apps/provider/AgeRatingProvider.kt | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt index 6914a74c6..44368820c 100644 --- a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +++ b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt @@ -35,10 +35,8 @@ import foundation.e.apps.contract.ParentalControlContract.COLUMN_PACKAGE_NAME import foundation.e.apps.contract.ParentalControlContract.PATH_BLOCKLIST import foundation.e.apps.contract.ParentalControlContract.PATH_LOGIN_TYPE import foundation.e.apps.contract.ParentalControlContract.getAppLoungeProviderAuthority -import foundation.e.apps.data.application.apps.AppsApi import foundation.e.apps.data.blockedApps.ContentRatingsRepository import foundation.e.apps.data.enums.Origin -import foundation.e.apps.data.enums.Type import foundation.e.apps.data.install.models.AppInstall import foundation.e.apps.data.login.AuthenticatorRepository import foundation.e.apps.data.preference.DataStoreManager @@ -61,7 +59,6 @@ class AgeRatingProvider : ContentProvider() { fun provideContentRatingsRepository(): ContentRatingsRepository fun provideValidateAppAgeLimitUseCase(): ValidateAppAgeLimitUseCase fun provideDataStoreManager(): DataStoreManager - fun provideAppsApi(): AppsApi } private lateinit var authenticatorRepository: AuthenticatorRepository @@ -69,7 +66,6 @@ class AgeRatingProvider : ContentProvider() { private lateinit var contentRatingsRepository: ContentRatingsRepository private lateinit var validateAppAgeLimitUseCase: ValidateAppAgeLimitUseCase private lateinit var dataStoreManager: DataStoreManager - private lateinit var appsApi: AppsApi private enum class UriCode(val code: Int) { LoginType(1), @@ -111,6 +107,7 @@ class AgeRatingProvider : ContentProvider() { val cursor = MatrixCursor(arrayOf(COLUMN_PACKAGE_NAME)) val packageNames = appLoungePackageManager.getAllUserApps().map { it.packageName } runBlocking { + Timber.d("Start preparing blocklist from ${packageNames.size} apps.") withContext(IO) { try { if (packageNames.isEmpty()) return@withContext cursor @@ -128,8 +125,18 @@ class AgeRatingProvider : ContentProvider() { } private suspend fun ensureAgeGroupDataExists() { - if (contentRatingsRepository.contentRatingGroups.isEmpty()) { - contentRatingsRepository.fetchContentRatingData() + withContext(IO) { + val deferredFetchRatings = async { + if (contentRatingsRepository.contentRatingGroups.isEmpty()) { + contentRatingsRepository.fetchContentRatingData() + } + } + val deferredFetchNSFW = async { + if (contentRatingsRepository.fDroidNSFWApps.isEmpty()) { + contentRatingsRepository.fetchNSFWApps() + } + } + listOf(deferredFetchRatings, deferredFetchNSFW).awaitAll() } } @@ -156,13 +163,9 @@ class AgeRatingProvider : ContentProvider() { } private suspend fun getNSFWValidity(packageName: String): Boolean { - val cleanapkApp = appsApi.getCleanapkAppDetails(packageName).first val fakeAppInstall = AppInstall( packageName = packageName, - origin = Origin.CLEANAPK, - type = Type.NATIVE, ) - fakeAppInstall.antiFeatures = cleanapkApp.antiFeatures val validateResult = validateAppAgeLimitUseCase(fakeAppInstall) return validateResult.data ?: false } @@ -180,7 +183,6 @@ class AgeRatingProvider : ContentProvider() { packageNames: List, ) { withContext(IO) { - Timber.d("Start blocklist for ${packageNames.size} apps.") val validityList = packageNames.map { packageName -> async { shouldAllow(packageName) @@ -192,7 +194,7 @@ class AgeRatingProvider : ContentProvider() { cursor.addRow(arrayOf(packageNames[index])) } } - Timber.d("Finished compiling blocklist") + Timber.d("Finished compiling blocklist - ${cursor.count} apps blocked.") } } @@ -206,7 +208,6 @@ class AgeRatingProvider : ContentProvider() { contentRatingsRepository = hiltEntryPoint.provideContentRatingsRepository() validateAppAgeLimitUseCase = hiltEntryPoint.provideValidateAppAgeLimitUseCase() dataStoreManager = hiltEntryPoint.provideDataStoreManager() - appsApi = hiltEntryPoint.provideAppsApi() return true } -- GitLab From 6cdf2b8641646d355a92b8d32d53739ed3ac47d6 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 15:55:42 +0530 Subject: [PATCH 09/20] add back check with antifeatures --- .../e/apps/domain/ValidateAppAgeLimitUseCase.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index 7dcf00519..336db12da 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -43,14 +43,27 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) - isNsfwFDroidApp(app) -> ResultSupreme.Success(data = false) + isFDroidApp(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) + isNsfwFDroidApp(app.packageName) -> ResultSupreme.Success(data = false) hasNoContentRating(app) -> ResultSupreme.Error(data = false) else -> validateAgeLimit(ageGroup, app) } } + private fun isFDroidApp(app: AppInstall): Boolean { + return app.id.isNotBlank() + && app.origin == Origin.CLEANAPK + && app.type == Type.NATIVE + } + private fun isNsfwFDroidApp(app: AppInstall): Boolean { - return app.packageName in contentRatingRepository.fDroidNSFWApps + return app.antiFeatures.any { + antiFeature -> antiFeature.containsKey(KEY_ANTI_FEATURES_NSFW) + } + } + + private fun isNsfwFDroidApp(packageName: String): Boolean { + return packageName in contentRatingRepository.fDroidNSFWApps } private fun validateAgeLimit( -- GitLab From a2713925cd2aad0cf47faef1c58ab7a37af22ecb Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 18:07:19 +0530 Subject: [PATCH 10/20] improve f-droid NSFW detection --- .../e/apps/domain/ValidateAppAgeLimitUseCase.kt | 14 +++++++++----- .../e/apps/provider/AgeRatingProvider.kt | 10 +++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index 336db12da..64e13ffc2 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -19,6 +19,7 @@ package foundation.e.apps.domain import foundation.e.apps.data.ResultSupreme +import foundation.e.apps.data.application.apps.AppsApi import foundation.e.apps.data.blockedApps.Age import foundation.e.apps.data.blockedApps.ContentRatingGroup import foundation.e.apps.data.blockedApps.ContentRatingsRepository @@ -32,10 +33,11 @@ import javax.inject.Inject class ValidateAppAgeLimitUseCase @Inject constructor( private val contentRatingRepository: ContentRatingsRepository, private val parentalControlRepository: ParentalControlRepository, + private val appsApi: AppsApi, ) { companion object { - private const val KEY_ANTI_FEATURES_NSFW = "NSFW" + const val KEY_ANTI_FEATURES_NSFW = "NSFW" } suspend operator fun invoke(app: AppInstall): ResultSupreme { @@ -43,8 +45,8 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) - isFDroidApp(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) isNsfwFDroidApp(app.packageName) -> ResultSupreme.Success(data = false) + isFDroidApp(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) hasNoContentRating(app) -> ResultSupreme.Error(data = false) else -> validateAgeLimit(ageGroup, app) } @@ -56,9 +58,11 @@ class ValidateAppAgeLimitUseCase @Inject constructor( && app.type == Type.NATIVE } - private fun isNsfwFDroidApp(app: AppInstall): Boolean { - return app.antiFeatures.any { - antiFeature -> antiFeature.containsKey(KEY_ANTI_FEATURES_NSFW) + private suspend fun isNsfwFDroidApp(app: AppInstall): Boolean { + return appsApi.getCleanapkAppDetails(app.packageName).first.let { it -> + it.antiFeatures.any { antiFeature -> + antiFeature.containsKey(KEY_ANTI_FEATURES_NSFW) + } } } diff --git a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt index 44368820c..c302a9a8f 100644 --- a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +++ b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt @@ -153,27 +153,27 @@ class AgeRatingProvider : ContentProvider() { return false } - private suspend fun getAppAgeValidity(packageName: String): Boolean { + private suspend fun getAppAgeValidity(packageName: String): Boolean? { val fakeAppInstall = AppInstall( packageName = packageName, origin = Origin.GPLAY ) - val validateResult = validateAppAgeLimitUseCase(fakeAppInstall) - return validateResult.data ?: false + val validateResult = validateAppAgeLimitUseCase.invoke(fakeAppInstall) + return validateResult.data } private suspend fun getNSFWValidity(packageName: String): Boolean { val fakeAppInstall = AppInstall( packageName = packageName, ) - val validateResult = validateAppAgeLimitUseCase(fakeAppInstall) + val validateResult = validateAppAgeLimitUseCase.invoke(fakeAppInstall) return validateResult.data ?: false } private suspend fun shouldAllow(packageName: String): Boolean { return when { !getNSFWValidity(packageName) -> false - !getAppAgeValidity(packageName) -> false + getAppAgeValidity(packageName) == false -> false else -> true } } -- GitLab From 5aa7833da74bf29db33cfe6ab126569826fc163c Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 19:09:25 +0530 Subject: [PATCH 11/20] whitelist safe f-droid apps and PWAs --- .../e/apps/domain/ValidateAppAgeLimitUseCase.kt | 15 ++++++++++++--- .../e/apps/provider/AgeRatingProvider.kt | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index 64e13ffc2..de6670f70 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -46,18 +46,27 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) isNsfwFDroidApp(app.packageName) -> ResultSupreme.Success(data = false) - isFDroidApp(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) - hasNoContentRating(app) -> ResultSupreme.Error(data = false) + isFDroidDownload(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) + // Whitelist apps which are from cleanapk but not caught by above NSFW filters. + // This includes safe F-droid apps. + // Also whitelists PWAs. + isCleanApkApp(app) -> ResultSupreme.Success(data = true) + // Check for GPlay apps now + hasNoContentRating(app) -> ResultSupreme.Error() else -> validateAgeLimit(ageGroup, app) } } - private fun isFDroidApp(app: AppInstall): Boolean { + private fun isFDroidDownload(app: AppInstall): Boolean { return app.id.isNotBlank() && app.origin == Origin.CLEANAPK && app.type == Type.NATIVE } + private fun isCleanApkApp(app: AppInstall): Boolean { + return app.origin == Origin.CLEANAPK + } + private suspend fun isNsfwFDroidApp(app: AppInstall): Boolean { return appsApi.getCleanapkAppDetails(app.packageName).first.let { it -> it.antiFeatures.any { antiFeature -> diff --git a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt index c302a9a8f..dac475a4c 100644 --- a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +++ b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt @@ -165,6 +165,7 @@ class AgeRatingProvider : ContentProvider() { private suspend fun getNSFWValidity(packageName: String): Boolean { val fakeAppInstall = AppInstall( packageName = packageName, + origin = Origin.CLEANAPK, ) val validateResult = validateAppAgeLimitUseCase.invoke(fakeAppInstall) return validateResult.data ?: false -- GitLab From 1dea18d03833d09247908de038acc2133432ec22 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Tue, 18 Jun 2024 19:57:45 +0600 Subject: [PATCH 12/20] initialization of antifeatures of appinstall --- .../foundation/e/apps/install/workmanager/AppInstallProcessor.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt b/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt index 4a269e555..cfba686e1 100644 --- a/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt +++ b/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt @@ -95,6 +95,7 @@ class AppInstallProcessor @Inject constructor( application.originalSize ).also { it.contentRating = application.contentRating + it.antiFeatures = application.antiFeatures } if (appInstall.type == Type.PWA) { -- GitLab From 253ef13ba10e3c0a1f2ff739dd4de01d1e29e8ba Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 14:39:21 +0000 Subject: [PATCH 13/20] Apply 4 suggestion(s) to 2 file(s) Co-authored-by: Jonathan Klee --- .../e/apps/data/blockedApps/ContentRatingsRepository.kt | 5 ++--- .../java/foundation/e/apps/provider/AgeRatingProvider.kt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt b/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt index de7637613..a3d77f952 100644 --- a/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt +++ b/app/src/main/java/foundation/e/apps/data/blockedApps/ContentRatingsRepository.kt @@ -40,7 +40,7 @@ class ContentRatingsRepository @Inject constructor( get() = _contentRatingGroups var fDroidNSFWApps = listOf() - private set + private set suspend fun fetchContentRatingData() { val response = ageGroupApi.getDefinedAgeGroups() @@ -50,8 +50,7 @@ class ContentRatingsRepository @Inject constructor( } suspend fun fetchNSFWApps() { - val fDroidMonitorData = fDroidMonitorApi.getMonitorData() - fDroidNSFWApps = fDroidMonitorData.body()?.getNSFWApps() ?: emptyList() + fDroidNSFWApps = fDroidMonitorApi.getMonitorData().body()?.getNSFWApps() ?: emptyList() } suspend fun getEnglishContentRating(packageName: String): ContentRating? { diff --git a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt index dac475a4c..4876f428d 100644 --- a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +++ b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt @@ -153,7 +153,7 @@ class AgeRatingProvider : ContentProvider() { return false } - private suspend fun getAppAgeValidity(packageName: String): Boolean? { + private suspend fun isAppValidRegardingAge(packageName: String): Boolean? { val fakeAppInstall = AppInstall( packageName = packageName, origin = Origin.GPLAY @@ -162,7 +162,7 @@ class AgeRatingProvider : ContentProvider() { return validateResult.data } - private suspend fun getNSFWValidity(packageName: String): Boolean { + private suspend fun isAppValidRegardingNSWF(packageName: String): Boolean { val fakeAppInstall = AppInstall( packageName = packageName, origin = Origin.CLEANAPK, -- GitLab From b59c1cc5ecace957bfd42ef48978ddf664b1fb87 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 20:21:08 +0530 Subject: [PATCH 14/20] modify get request --- .../java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt b/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt index 099bab95f..ed9de2185 100644 --- a/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt +++ b/app/src/main/java/foundation/e/apps/data/ageRating/FDroidMonitorApi.kt @@ -25,10 +25,10 @@ import retrofit2.http.GET interface FDroidMonitorApi { companion object { - const val BASE_URL = "https://f-droid.org/repo/status/" + const val BASE_URL = "https://f-droid.org/repo/" } - @GET("update.json") + @GET("status/update.json") suspend fun getMonitorData(): Response } -- GitLab From dfdc25ce847afc936910ff9afc38390af92e3e4c Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 20:30:02 +0530 Subject: [PATCH 15/20] fix method renames --- .../main/java/foundation/e/apps/provider/AgeRatingProvider.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt index 4876f428d..73fe65ccf 100644 --- a/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt +++ b/app/src/main/java/foundation/e/apps/provider/AgeRatingProvider.kt @@ -173,8 +173,8 @@ class AgeRatingProvider : ContentProvider() { private suspend fun shouldAllow(packageName: String): Boolean { return when { - !getNSFWValidity(packageName) -> false - getAppAgeValidity(packageName) == false -> false + !isAppValidRegardingNSWF(packageName) -> false + isAppValidRegardingAge(packageName) == false -> false else -> true } } -- GitLab From baf5a5bececfb93de4817ba72cd049dbf60d66ed Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 20:37:03 +0530 Subject: [PATCH 16/20] change method name --- .../foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index de6670f70..c740f3599 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -45,7 +45,7 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) - isNsfwFDroidApp(app.packageName) -> ResultSupreme.Success(data = false) + isKnownNsfwApp(app) -> ResultSupreme.Success(data = false) isFDroidDownload(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) // Whitelist apps which are from cleanapk but not caught by above NSFW filters. // This includes safe F-droid apps. @@ -75,8 +75,8 @@ class ValidateAppAgeLimitUseCase @Inject constructor( } } - private fun isNsfwFDroidApp(packageName: String): Boolean { - return packageName in contentRatingRepository.fDroidNSFWApps + private fun isKnownNsfwApp(app: AppInstall): Boolean { + return app.packageName in contentRatingRepository.fDroidNSFWApps } private fun validateAgeLimit( -- GitLab From d6386cff93abffc431ea5bc7b6980d9c945d342d Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 16:21:43 +0000 Subject: [PATCH 17/20] Apply 3 suggestion(s) to 1 file(s) Co-authored-by: Jonathan Klee --- .../foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index c740f3599..c2e6ab835 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -47,12 +47,8 @@ class ValidateAppAgeLimitUseCase @Inject constructor( isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) isKnownNsfwApp(app) -> ResultSupreme.Success(data = false) isFDroidDownload(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) - // Whitelist apps which are from cleanapk but not caught by above NSFW filters. - // This includes safe F-droid apps. - // Also whitelists PWAs. isCleanApkApp(app) -> ResultSupreme.Success(data = true) - // Check for GPlay apps now - hasNoContentRating(app) -> ResultSupreme.Error() + hasNoContentRatingOnGPlay(app) -> ResultSupreme.Error() else -> validateAgeLimit(ageGroup, app) } } -- GitLab From 8ac4fe5ba19357c2783dcc093656898dec64e831 Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Tue, 18 Jun 2024 21:53:11 +0530 Subject: [PATCH 18/20] rename method --- .../java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index c2e6ab835..5edf26929 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -91,7 +91,7 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return ResultSupreme.Success(isValidAppAgeRating(app, allowedContentRating)) } - private suspend fun hasNoContentRating(app: AppInstall) = + private suspend fun hasNoContentRatingOnGPlay(app: AppInstall) = !verifyContentRatingExists(app) private fun isValidAppAgeRating( -- GitLab From 7ae08809a7f5f67deb44647cc568fd0d121d42a9 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Tue, 18 Jun 2024 20:07:19 +0600 Subject: [PATCH 19/20] Revert "initialization of antifeatures of appinstall" This reverts commit 1dea18d03833d09247908de038acc2133432ec22. --- .../foundation/e/apps/install/workmanager/AppInstallProcessor.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt b/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt index cfba686e1..4a269e555 100644 --- a/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt +++ b/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt @@ -95,7 +95,6 @@ class AppInstallProcessor @Inject constructor( application.originalSize ).also { it.contentRating = application.contentRating - it.antiFeatures = application.antiFeatures } if (appInstall.type == Type.PWA) { -- GitLab From 3914e4443885a5181ab72ded4895e919d450ab19 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Wed, 19 Jun 2024 00:24:34 +0600 Subject: [PATCH 20/20] refactor: renaming methods, code cleanup --- .../e/apps/data/install/models/AppInstall.kt | 3 --- .../e/apps/domain/ValidateAppAgeLimitUseCase.kt | 13 +++++++------ .../apps/install/workmanager/AppInstallProcessor.kt | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt b/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt index 71ca2ffef..28f92b4d6 100644 --- a/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt +++ b/app/src/main/java/foundation/e/apps/data/install/models/AppInstall.kt @@ -40,9 +40,6 @@ data class AppInstall( @Ignore var contentRating: ContentRating = ContentRating() - @Ignore - var antiFeatures: List> = emptyList() - fun isAppInstalling() = installingStatusList.contains(status) fun isAwaiting() = status == Status.AWAITING diff --git a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt index 5edf26929..f94648b50 100644 --- a/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt +++ b/app/src/main/java/foundation/e/apps/domain/ValidateAppAgeLimitUseCase.kt @@ -46,25 +46,26 @@ class ValidateAppAgeLimitUseCase @Inject constructor( return when { isParentalControlDisabled(ageGroup) -> ResultSupreme.Success(data = true) isKnownNsfwApp(app) -> ResultSupreme.Success(data = false) - isFDroidDownload(app) -> ResultSupreme.Success(!isNsfwFDroidApp(app)) - isCleanApkApp(app) -> ResultSupreme.Success(data = true) + isCleanApkApp(app) -> ResultSupreme.Success(!isNsfwAppByCleanApkApi(app)) + isWhiteListedCleanApkApp(app) -> ResultSupreme.Success(data = true) + // Check for GPlay apps now hasNoContentRatingOnGPlay(app) -> ResultSupreme.Error() else -> validateAgeLimit(ageGroup, app) } } - private fun isFDroidDownload(app: AppInstall): Boolean { + private fun isCleanApkApp(app: AppInstall): Boolean { return app.id.isNotBlank() && app.origin == Origin.CLEANAPK && app.type == Type.NATIVE } - private fun isCleanApkApp(app: AppInstall): Boolean { + private fun isWhiteListedCleanApkApp(app: AppInstall): Boolean { return app.origin == Origin.CLEANAPK } - private suspend fun isNsfwFDroidApp(app: AppInstall): Boolean { - return appsApi.getCleanapkAppDetails(app.packageName).first.let { it -> + private suspend fun isNsfwAppByCleanApkApi(app: AppInstall): Boolean { + return appsApi.getCleanapkAppDetails(app.packageName).first.let { it.antiFeatures.any { antiFeature -> antiFeature.containsKey(KEY_ANTI_FEATURES_NSFW) } diff --git a/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt b/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt index 4a269e555..77fbf8b44 100644 --- a/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt +++ b/app/src/main/java/foundation/e/apps/install/workmanager/AppInstallProcessor.kt @@ -132,7 +132,7 @@ class AppInstallProcessor @Inject constructor( } val ageLimitValidationResult = validateAppAgeLimitUseCase.invoke(appInstall) - if (ageLimitValidationResult.data == false) { + if (ageLimitValidationResult.data != true) { if (ageLimitValidationResult.isSuccess()) { Timber.i("Content rating is not allowed for: ${appInstall.name}") EventBus.invokeEvent(AppEvent.AgeLimitRestrictionEvent(appInstall.name)) -- GitLab