Loading app/src/main/java/foundation/e/apps/data/database/install/AppInstallDatabase.kt +18 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.database.install import android.content.Context Loading app/src/main/java/foundation/e/apps/data/install/AppInstallIconUrlBuilder.kt 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.install import foundation.e.apps.data.cleanapk.CleanApkRetrofit import foundation.e.apps.data.installation.model.InstallationSource import javax.inject.Inject class AppInstallIconUrlBuilder @Inject constructor() { fun build(source: InstallationSource, iconImageUrl: String): String { return if (source == InstallationSource.PLAY_STORE || source == InstallationSource.PWA) { "${CleanApkRetrofit.ASSET_URL}$iconImageUrl" } else { iconImageUrl } } } app/src/main/java/foundation/e/apps/data/install/AppInstallMappings.kt 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.install import foundation.e.apps.data.enums.Source import foundation.e.apps.data.enums.Type import foundation.e.apps.data.installation.model.InstallationSource import foundation.e.apps.data.installation.model.InstallationType fun Source.toInstallationSource(): InstallationSource { return when (this) { Source.OPEN_SOURCE -> InstallationSource.OPEN_SOURCE Source.PWA -> InstallationSource.PWA Source.SYSTEM_APP -> InstallationSource.SYSTEM_APP Source.PLAY_STORE -> InstallationSource.PLAY_STORE } } fun Type.toInstallationType(): InstallationType { return when (this) { Type.NATIVE -> InstallationType.NATIVE Type.PWA -> InstallationType.PWA } } fun InstallationSource.toAppSource(): Source { return when (this) { InstallationSource.OPEN_SOURCE -> Source.OPEN_SOURCE InstallationSource.PWA -> Source.PWA InstallationSource.SYSTEM_APP -> Source.SYSTEM_APP InstallationSource.PLAY_STORE -> Source.PLAY_STORE } } fun InstallationType.toAppType(): Type { return when (this) { InstallationType.NATIVE -> Type.NATIVE InstallationType.PWA -> Type.PWA } } app/src/main/java/foundation/e/apps/data/install/AppManagerImpl.kt +4 −4 Original line number Diff line number Diff line Loading @@ -28,12 +28,12 @@ import androidx.core.net.toUri import androidx.lifecycle.LiveData import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.R import foundation.e.apps.data.enums.Type import foundation.e.apps.data.install.download.data.DownloadProgressLD import foundation.e.apps.data.install.models.AppInstall import foundation.e.apps.data.install.pkg.AppLoungePackageManager import foundation.e.apps.data.install.pkg.PwaManager import foundation.e.apps.data.install.sharedlib.SharedLibraryManager import foundation.e.apps.data.installation.model.InstallationType import foundation.e.apps.data.parentalcontrol.ContentRatingDao import foundation.e.apps.data.parentalcontrol.ContentRatingEntity import foundation.e.apps.domain.model.install.Status Loading Loading @@ -129,8 +129,8 @@ class AppManagerImpl @Inject constructor( override suspend fun downloadApp(appInstall: AppInstall, isUpdate: Boolean) { mutex.withLock { when (appInstall.type) { Type.NATIVE -> downloadNativeApp(appInstall, isUpdate) Type.PWA -> pwaManager.installPWAApp(appInstall) InstallationType.NATIVE -> downloadNativeApp(appInstall, isUpdate) InstallationType.PWA -> pwaManager.installPWAApp(appInstall) } } } Loading @@ -138,7 +138,7 @@ class AppManagerImpl @Inject constructor( override suspend fun installApp(appInstall: AppInstall) { val list = mutableListOf<File>() when (appInstall.type) { Type.NATIVE -> { InstallationType.NATIVE -> { // Collect main app APKs (exclude the libraries/ subdir) val parentPathFile = File("$cacheDir/${appInstall.packageName}") parentPathFile.listFiles { f -> f.isFile && f.name.endsWith(".apk") } Loading app/src/main/java/foundation/e/apps/data/install/core/AppInstallationFacade.kt +3 −0 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package foundation.e.apps.data.install.core import foundation.e.apps.data.application.ApplicationRepository import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Source import foundation.e.apps.data.install.AppManagerWrapper import foundation.e.apps.data.install.models.AppInstall import foundation.e.apps.domain.model.install.Status Loading @@ -30,6 +32,7 @@ class AppInstallationFacade @Inject constructor( private val installationEnqueuer: InstallationEnqueuer, private val installationProcessor: InstallationProcessor, private val installationRequest: InstallationRequest, private val applicationRepository: ApplicationRepository, ) { /** * creates [AppInstall] from [Application] and enqueues into WorkManager to run install process. Loading Loading
app/src/main/java/foundation/e/apps/data/database/install/AppInstallDatabase.kt +18 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.database.install import android.content.Context Loading
app/src/main/java/foundation/e/apps/data/install/AppInstallIconUrlBuilder.kt 0 → 100644 +33 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.install import foundation.e.apps.data.cleanapk.CleanApkRetrofit import foundation.e.apps.data.installation.model.InstallationSource import javax.inject.Inject class AppInstallIconUrlBuilder @Inject constructor() { fun build(source: InstallationSource, iconImageUrl: String): String { return if (source == InstallationSource.PLAY_STORE || source == InstallationSource.PWA) { "${CleanApkRetrofit.ASSET_URL}$iconImageUrl" } else { iconImageUrl } } }
app/src/main/java/foundation/e/apps/data/install/AppInstallMappings.kt 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2026 e Foundation * * 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.data.install import foundation.e.apps.data.enums.Source import foundation.e.apps.data.enums.Type import foundation.e.apps.data.installation.model.InstallationSource import foundation.e.apps.data.installation.model.InstallationType fun Source.toInstallationSource(): InstallationSource { return when (this) { Source.OPEN_SOURCE -> InstallationSource.OPEN_SOURCE Source.PWA -> InstallationSource.PWA Source.SYSTEM_APP -> InstallationSource.SYSTEM_APP Source.PLAY_STORE -> InstallationSource.PLAY_STORE } } fun Type.toInstallationType(): InstallationType { return when (this) { Type.NATIVE -> InstallationType.NATIVE Type.PWA -> InstallationType.PWA } } fun InstallationSource.toAppSource(): Source { return when (this) { InstallationSource.OPEN_SOURCE -> Source.OPEN_SOURCE InstallationSource.PWA -> Source.PWA InstallationSource.SYSTEM_APP -> Source.SYSTEM_APP InstallationSource.PLAY_STORE -> Source.PLAY_STORE } } fun InstallationType.toAppType(): Type { return when (this) { InstallationType.NATIVE -> Type.NATIVE InstallationType.PWA -> Type.PWA } }
app/src/main/java/foundation/e/apps/data/install/AppManagerImpl.kt +4 −4 Original line number Diff line number Diff line Loading @@ -28,12 +28,12 @@ import androidx.core.net.toUri import androidx.lifecycle.LiveData import dagger.hilt.android.qualifiers.ApplicationContext import foundation.e.apps.R import foundation.e.apps.data.enums.Type import foundation.e.apps.data.install.download.data.DownloadProgressLD import foundation.e.apps.data.install.models.AppInstall import foundation.e.apps.data.install.pkg.AppLoungePackageManager import foundation.e.apps.data.install.pkg.PwaManager import foundation.e.apps.data.install.sharedlib.SharedLibraryManager import foundation.e.apps.data.installation.model.InstallationType import foundation.e.apps.data.parentalcontrol.ContentRatingDao import foundation.e.apps.data.parentalcontrol.ContentRatingEntity import foundation.e.apps.domain.model.install.Status Loading Loading @@ -129,8 +129,8 @@ class AppManagerImpl @Inject constructor( override suspend fun downloadApp(appInstall: AppInstall, isUpdate: Boolean) { mutex.withLock { when (appInstall.type) { Type.NATIVE -> downloadNativeApp(appInstall, isUpdate) Type.PWA -> pwaManager.installPWAApp(appInstall) InstallationType.NATIVE -> downloadNativeApp(appInstall, isUpdate) InstallationType.PWA -> pwaManager.installPWAApp(appInstall) } } } Loading @@ -138,7 +138,7 @@ class AppManagerImpl @Inject constructor( override suspend fun installApp(appInstall: AppInstall) { val list = mutableListOf<File>() when (appInstall.type) { Type.NATIVE -> { InstallationType.NATIVE -> { // Collect main app APKs (exclude the libraries/ subdir) val parentPathFile = File("$cacheDir/${appInstall.packageName}") parentPathFile.listFiles { f -> f.isFile && f.name.endsWith(".apk") } Loading
app/src/main/java/foundation/e/apps/data/install/core/AppInstallationFacade.kt +3 −0 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package foundation.e.apps.data.install.core import foundation.e.apps.data.application.ApplicationRepository import foundation.e.apps.data.application.data.Application import foundation.e.apps.data.enums.ResultStatus import foundation.e.apps.data.enums.Source import foundation.e.apps.data.install.AppManagerWrapper import foundation.e.apps.data.install.models.AppInstall import foundation.e.apps.domain.model.install.Status Loading @@ -30,6 +32,7 @@ class AppInstallationFacade @Inject constructor( private val installationEnqueuer: InstallationEnqueuer, private val installationProcessor: InstallationProcessor, private val installationRequest: InstallationRequest, private val applicationRepository: ApplicationRepository, ) { /** * creates [AppInstall] from [Application] and enqueues into WorkManager to run install process. Loading