Loading app/build.gradle +4 −1 Original line number Diff line number Diff line plugins { id 'com.android.application' id 'kotlin-android' Loading Loading @@ -113,7 +114,7 @@ android { lintConfig file('lint.xml') } kotlin.sourceSets.all { languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn") languageSettings.optIn("kotlin.RequiresOptIn") } } Loading Loading @@ -156,6 +157,8 @@ dependencies { testImplementation 'org.mockito:mockito-inline:2.13.0' testImplementation "androidx.arch.core:core-testing:2.1.0" testImplementation "io.mockk:mockk:1.12.3" // Coil and PhotoView implementation "io.coil-kt:coil:1.4.0" implementation 'com.github.Baseflow:PhotoView:2.3.0' Loading app/src/main/java/foundation/e/apps/api/DownloadManager.kt +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package foundation.e.apps.api import android.app.DownloadManager import android.net.Uri import foundation.e.apps.OpenForTesting import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay Loading @@ -34,6 +35,7 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @Singleton @OpenForTesting class DownloadManager @Inject constructor( private val downloadManager: DownloadManager, @Named("cacheDir") private val cacheDir: String, Loading app/src/main/java/foundation/e/apps/api/fdroid/FdroidRepository.kt +5 −5 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ import javax.inject.Singleton class FdroidRepository @Inject constructor( private val fdroidApi: FdroidApiInterface, private val fdroidDao: FdroidDao, ) { ) : IFdroidRepository { companion object { const val UNKNOWN = "unknown" Loading @@ -26,7 +26,7 @@ class FdroidRepository @Inject constructor( * * Result may be null. */ private suspend fun getFdroidInfo(packageName: String): FdroidEntity? { override suspend fun getFdroidInfo(packageName: String): FdroidEntity? { return fdroidDao.getFdroidEntityFromPackageName(packageName) ?: fdroidApi.getFdroidInfoForPackage(packageName).body()?.let { FdroidEntity(packageName, it.authorName).also { Loading @@ -35,7 +35,7 @@ class FdroidRepository @Inject constructor( } } suspend fun getAuthorName(fusedApp: FusedApp): String { override suspend fun getAuthorName(fusedApp: FusedApp): String { if (fusedApp.author != UNKNOWN || fusedApp.origin != Origin.CLEANAPK) { return fusedApp.author.ifEmpty { UNKNOWN } } Loading @@ -49,14 +49,14 @@ class FdroidRepository @Inject constructor( return result?.authorName ?: FdroidEntity.DEFAULT_FDROID_AUTHOR_NAME } suspend fun isFdroidApplicationSigned(context: Context, packageName: String, apkFilePath: String, signature: String): Boolean { override suspend fun isFdroidApplicationSigned(context: Context, packageName: String, apkFilePath: String, signature: String): Boolean { if (isFdroidApplication(packageName)) { return ApkSignatureManager.verifyFdroidSignature(context, apkFilePath, signature) } return false } private suspend fun isFdroidApplication(packageName: String): Boolean { override suspend fun isFdroidApplication(packageName: String): Boolean { return fdroidApi.getFdroidInfoForPackage(packageName).isSuccessful } } app/src/main/java/foundation/e/apps/api/fdroid/IFdroidRepository.kt 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright MURENA SAS 2023 * 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 <https://www.gnu.org/licenses/>. */ package foundation.e.apps.api.fdroid import android.content.Context import foundation.e.apps.api.fdroid.models.FdroidEntity import foundation.e.apps.api.fused.data.FusedApp interface IFdroidRepository { /** * Get Fdroid entity from DB is present. * If not present then make an API call, store the fetched result and return the result. * * Result may be null. */ suspend fun getFdroidInfo(packageName: String): FdroidEntity? suspend fun getAuthorName(fusedApp: FusedApp): String suspend fun isFdroidApplicationSigned( context: Context, packageName: String, apkFilePath: String, signature: String ): Boolean suspend fun isFdroidApplication(packageName: String): Boolean } app/src/main/java/foundation/e/apps/di/RepositoryModule.kt +12 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.api.exodus.repositories.AppPrivacyInfoRepositoryImpl import foundation.e.apps.api.exodus.repositories.IAppPrivacyInfoRepository import foundation.e.apps.api.fdroid.FdroidRepository import foundation.e.apps.api.fdroid.IFdroidRepository import foundation.e.apps.manager.fused.FusedManagerImpl import foundation.e.apps.manager.fused.IFusedManager import javax.inject.Singleton @Module Loading @@ -14,4 +18,12 @@ interface RepositoryModule { @Singleton @Binds fun getRepositoryModule(trackerRepositoryImpl: AppPrivacyInfoRepositoryImpl): IAppPrivacyInfoRepository @Singleton @Binds fun getFusedManagerImpl(fusedManagerImpl: FusedManagerImpl): IFusedManager @Singleton @Binds fun getFdroidRepository(fusedManagerImpl: FdroidRepository): IFdroidRepository } Loading
app/build.gradle +4 −1 Original line number Diff line number Diff line plugins { id 'com.android.application' id 'kotlin-android' Loading Loading @@ -113,7 +114,7 @@ android { lintConfig file('lint.xml') } kotlin.sourceSets.all { languageSettings.useExperimentalAnnotation("kotlin.RequiresOptIn") languageSettings.optIn("kotlin.RequiresOptIn") } } Loading Loading @@ -156,6 +157,8 @@ dependencies { testImplementation 'org.mockito:mockito-inline:2.13.0' testImplementation "androidx.arch.core:core-testing:2.1.0" testImplementation "io.mockk:mockk:1.12.3" // Coil and PhotoView implementation "io.coil-kt:coil:1.4.0" implementation 'com.github.Baseflow:PhotoView:2.3.0' Loading
app/src/main/java/foundation/e/apps/api/DownloadManager.kt +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package foundation.e.apps.api import android.app.DownloadManager import android.net.Uri import foundation.e.apps.OpenForTesting import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay Loading @@ -34,6 +35,7 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @Singleton @OpenForTesting class DownloadManager @Inject constructor( private val downloadManager: DownloadManager, @Named("cacheDir") private val cacheDir: String, Loading
app/src/main/java/foundation/e/apps/api/fdroid/FdroidRepository.kt +5 −5 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ import javax.inject.Singleton class FdroidRepository @Inject constructor( private val fdroidApi: FdroidApiInterface, private val fdroidDao: FdroidDao, ) { ) : IFdroidRepository { companion object { const val UNKNOWN = "unknown" Loading @@ -26,7 +26,7 @@ class FdroidRepository @Inject constructor( * * Result may be null. */ private suspend fun getFdroidInfo(packageName: String): FdroidEntity? { override suspend fun getFdroidInfo(packageName: String): FdroidEntity? { return fdroidDao.getFdroidEntityFromPackageName(packageName) ?: fdroidApi.getFdroidInfoForPackage(packageName).body()?.let { FdroidEntity(packageName, it.authorName).also { Loading @@ -35,7 +35,7 @@ class FdroidRepository @Inject constructor( } } suspend fun getAuthorName(fusedApp: FusedApp): String { override suspend fun getAuthorName(fusedApp: FusedApp): String { if (fusedApp.author != UNKNOWN || fusedApp.origin != Origin.CLEANAPK) { return fusedApp.author.ifEmpty { UNKNOWN } } Loading @@ -49,14 +49,14 @@ class FdroidRepository @Inject constructor( return result?.authorName ?: FdroidEntity.DEFAULT_FDROID_AUTHOR_NAME } suspend fun isFdroidApplicationSigned(context: Context, packageName: String, apkFilePath: String, signature: String): Boolean { override suspend fun isFdroidApplicationSigned(context: Context, packageName: String, apkFilePath: String, signature: String): Boolean { if (isFdroidApplication(packageName)) { return ApkSignatureManager.verifyFdroidSignature(context, apkFilePath, signature) } return false } private suspend fun isFdroidApplication(packageName: String): Boolean { override suspend fun isFdroidApplication(packageName: String): Boolean { return fdroidApi.getFdroidInfoForPackage(packageName).isSuccessful } }
app/src/main/java/foundation/e/apps/api/fdroid/IFdroidRepository.kt 0 → 100644 +44 −0 Original line number Diff line number Diff line /* * Copyright MURENA SAS 2023 * 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 <https://www.gnu.org/licenses/>. */ package foundation.e.apps.api.fdroid import android.content.Context import foundation.e.apps.api.fdroid.models.FdroidEntity import foundation.e.apps.api.fused.data.FusedApp interface IFdroidRepository { /** * Get Fdroid entity from DB is present. * If not present then make an API call, store the fetched result and return the result. * * Result may be null. */ suspend fun getFdroidInfo(packageName: String): FdroidEntity? suspend fun getAuthorName(fusedApp: FusedApp): String suspend fun isFdroidApplicationSigned( context: Context, packageName: String, apkFilePath: String, signature: String ): Boolean suspend fun isFdroidApplication(packageName: String): Boolean }
app/src/main/java/foundation/e/apps/di/RepositoryModule.kt +12 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,10 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.api.exodus.repositories.AppPrivacyInfoRepositoryImpl import foundation.e.apps.api.exodus.repositories.IAppPrivacyInfoRepository import foundation.e.apps.api.fdroid.FdroidRepository import foundation.e.apps.api.fdroid.IFdroidRepository import foundation.e.apps.manager.fused.FusedManagerImpl import foundation.e.apps.manager.fused.IFusedManager import javax.inject.Singleton @Module Loading @@ -14,4 +18,12 @@ interface RepositoryModule { @Singleton @Binds fun getRepositoryModule(trackerRepositoryImpl: AppPrivacyInfoRepositoryImpl): IAppPrivacyInfoRepository @Singleton @Binds fun getFusedManagerImpl(fusedManagerImpl: FusedManagerImpl): IFusedManager @Singleton @Binds fun getFdroidRepository(fusedManagerImpl: FdroidRepository): IFdroidRepository }