Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Verified Commit 4d9b256e authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

refactor: cleanup and remove thin wrappers

Remove install ports and *Impl wrappers that were only adding indirection inside
the app module.

App-side helpers now call the existing app services directly for
network checks, storage checks, parental control auth, and update tracking.

Keep only the installation ports that still define a real boundary with the data
module.

Simplify app event dispatch by providing the dispatcher directly from
Hilt instead of using a dedicated implementation class.

Update the related unit
tests to match the simplified wiring.
parent cc40ade2
Loading
Loading
Loading
Loading
Loading
+10 −35
Original line number Diff line number Diff line
@@ -20,54 +20,21 @@ package foundation.e.apps.data.di.bindings

import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.data.event.EventBus
import foundation.e.apps.data.install.core.helper.InstallationCompletionHandler
import foundation.e.apps.data.install.download.DownloadManagerUtils
import foundation.e.apps.data.install.wrapper.AppEventDispatcher
import foundation.e.apps.data.install.wrapper.AppEventDispatcherImpl
import foundation.e.apps.data.install.wrapper.DeviceNetworkStatusChecker
import foundation.e.apps.data.install.wrapper.ParentalControlAuthGatewayImpl
import foundation.e.apps.data.install.wrapper.StorageSpaceCheckerImpl
import foundation.e.apps.data.install.wrapper.UpdatesNotificationSenderImpl
import foundation.e.apps.data.install.wrapper.UpdatesTrackerImpl
import foundation.e.apps.data.installation.port.InstallationCompletionNotifier
import foundation.e.apps.data.installation.port.InstallationDownloadStatusUpdater
import foundation.e.apps.data.installation.port.NetworkStatusChecker
import foundation.e.apps.data.installation.port.ParentalControlAuthGateway
import foundation.e.apps.data.installation.port.StorageSpaceChecker
import foundation.e.apps.data.installation.port.UpdatesNotificationSender
import foundation.e.apps.data.installation.port.UpdatesTracker
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
interface AppInstallationModule {

    @Binds
    @Singleton
    fun bindAppEventDispatcher(dispatcher: AppEventDispatcherImpl): AppEventDispatcher

    @Binds
    @Singleton
    fun bindStorageSpaceChecker(checker: StorageSpaceCheckerImpl): StorageSpaceChecker

    @Binds
    @Singleton
    fun bindParentalControlAuthGateway(gateway: ParentalControlAuthGatewayImpl): ParentalControlAuthGateway

    @Binds
    @Singleton
    fun bindUpdatesTracker(tracker: UpdatesTrackerImpl): UpdatesTracker

    @Binds
    @Singleton
    fun bindUpdatesNotificationSender(sender: UpdatesNotificationSenderImpl): UpdatesNotificationSender

    @Binds
    @Singleton
    fun bindNetworkStatusChecker(checker: DeviceNetworkStatusChecker): NetworkStatusChecker

    @Binds
    @Singleton
    fun bindInstallationDownloadStatusUpdater(
@@ -77,4 +44,12 @@ interface AppInstallationModule {
    @Binds
    @Singleton
    fun bindInstallationCompletionNotifier(handler: InstallationCompletionHandler): InstallationCompletionNotifier

    companion object {
        @Provides
        @Singleton
        fun provideAppEventDispatcher(): AppEventDispatcher {
            return AppEventDispatcher { event -> EventBus.invokeEvent(event) }
        }
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -24,16 +24,16 @@ import foundation.e.apps.data.application.AppManager
import foundation.e.apps.data.event.AppEvent
import foundation.e.apps.data.install.wrapper.AppEventDispatcher
import foundation.e.apps.data.installation.model.AppInstall
import foundation.e.apps.data.installation.port.ParentalControlAuthGateway
import foundation.e.apps.data.system.ParentalControlAuthenticator
import foundation.e.apps.domain.ValidateAppAgeLimitUseCase
import foundation.e.apps.domain.model.ContentRatingValidity
import kotlinx.coroutines.CompletableDeferred
import javax.inject.Inject

class AgeLimiter @Inject constructor(
    private val validateAppAgeLimitUseCase: ValidateAppAgeLimitUseCase,
    private val appManager: AppManager,
    private val appEventDispatcher: AppEventDispatcher,
    private val parentalControlAuthGateway: ParentalControlAuthGateway,
) {
    suspend fun allow(appInstall: AppInstall): Boolean {
        val ageLimitValidationResult = validateAppAgeLimitUseCase(appInstall)
@@ -63,7 +63,7 @@ class AgeLimiter @Inject constructor(
    ): Boolean {
        awaitInvokeAgeLimitEvent(appName)
        if (ageLimitValidationResult.data?.requestPin == true &&
            parentalControlAuthGateway.awaitAuthentication()
            ParentalControlAuthenticator.awaitAuthentication()
        ) {
            ageLimitValidationResult.setData(ContentRatingValidity(true))
        }
+7 −6
Original line number Diff line number Diff line
@@ -18,23 +18,24 @@

package foundation.e.apps.data.install.core.helper

import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.data.application.AppManager
import foundation.e.apps.data.event.AppEvent
import foundation.e.apps.data.install.notification.StorageNotificationManager
import foundation.e.apps.data.install.wrapper.AppEventDispatcher
import foundation.e.apps.data.installation.model.AppInstall
import foundation.e.apps.data.installation.port.NetworkStatusChecker
import foundation.e.apps.data.installation.port.StorageSpaceChecker
import foundation.e.apps.data.system.StorageComputer
import foundation.e.apps.data.system.isNetworkAvailable
import timber.log.Timber
import javax.inject.Inject

class DevicePreconditions @Inject constructor(
    @ApplicationContext private val context: Context,
    private val appManager: AppManager,
    private val appEventDispatcher: AppEventDispatcher,
    private val storageNotificationManager: StorageNotificationManager,
    private val storageSpaceChecker: StorageSpaceChecker,
    private val networkStatusChecker: NetworkStatusChecker,
) {
    suspend fun canProceed(appInstall: AppInstall): Boolean {
        val hasNetwork = hasNetworkConnection(appInstall)
@@ -42,7 +43,7 @@ class DevicePreconditions @Inject constructor(
    }

    private suspend fun hasNetworkConnection(appInstall: AppInstall): Boolean {
        val hasNetwork = networkStatusChecker.isNetworkAvailable()
        val hasNetwork = context.isNetworkAvailable()
        if (!hasNetwork) {
            appManager.reportInstallationIssue(appInstall)
            appEventDispatcher.dispatch(AppEvent.NoInternetEvent(false))
@@ -51,7 +52,7 @@ class DevicePreconditions @Inject constructor(
    }

    private suspend fun hasStorageSpace(appInstall: AppInstall): Boolean {
        val missingStorage = storageSpaceChecker.spaceMissing(appInstall)
        val missingStorage = StorageComputer.spaceMissing(appInstall)
        if (missingStorage > 0) {
            Timber.d("Storage is not available for: ${appInstall.name} size: ${appInstall.appSize}")
            storageNotificationManager.showNotEnoughSpaceNotification(appInstall)
+8 −9
Original line number Diff line number Diff line
@@ -22,10 +22,10 @@ import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.apps.R
import foundation.e.apps.data.application.AppManager
import foundation.e.apps.data.application.UpdatesDao
import foundation.e.apps.data.install.updates.UpdatesNotifier
import foundation.e.apps.data.installation.model.AppInstall
import foundation.e.apps.data.installation.port.InstallationCompletionNotifier
import foundation.e.apps.data.installation.port.UpdatesNotificationSender
import foundation.e.apps.data.installation.port.UpdatesTracker
import foundation.e.apps.data.installation.repository.AppInstallRepository
import foundation.e.apps.data.preference.PlayStoreAuthStore
import foundation.e.apps.data.utils.getFormattedString
@@ -40,8 +40,6 @@ class InstallationCompletionHandler @Inject constructor(
    private val appInstallRepository: AppInstallRepository,
    private val appManager: AppManager,
    private val playStoreAuthStore: PlayStoreAuthStore,
    private val updatesTracker: UpdatesTracker,
    private val updatesNotificationSender: UpdatesNotificationSender,
) : InstallationCompletionNotifier {
    companion object {
        private const val DATE_FORMAT = "dd/MM/yyyy-HH:mm"
@@ -56,12 +54,12 @@ class InstallationCompletionHandler @Inject constructor(
            val packageStatus = appManager.getInstallationStatus(appInstall)

            if (packageStatus == Status.INSTALLED) {
                updatesTracker.addSuccessfullyUpdatedApp(it)
                UpdatesDao.addSuccessfullyUpdatedApp(it)
            }

            if (isUpdateCompleted()) {
                showNotificationOnUpdateEnded()
                updatesTracker.clearSuccessfullyUpdatedApps()
                UpdatesDao.clearSuccessfullyUpdatedApps()
            }
        }
    }
@@ -71,7 +69,7 @@ class InstallationCompletionHandler @Inject constructor(
            !listOf(Status.INSTALLATION_ISSUE, Status.PURCHASE_NEEDED).contains(it.status)
        }

        return updatesTracker.hasSuccessfulUpdatedApps() && downloadListWithoutAnyIssue.isEmpty()
        return UpdatesDao.successfulUpdatedApps.isNotEmpty() && downloadListWithoutAnyIssue.isEmpty()
    }

    private suspend fun showNotificationOnUpdateEnded() {
@@ -79,10 +77,11 @@ class InstallationCompletionHandler @Inject constructor(
        val date = Date().getFormattedString(DATE_FORMAT, locale)
        val numberOfUpdatedApps =
            NumberFormat.getNumberInstance(locale)
                .format(updatesTracker.successfulUpdatedAppsCount())
                .format(UpdatesDao.successfulUpdatedApps.size)
                .toString()

        updatesNotificationSender.showNotification(
        UpdatesNotifier.showNotification(
            context,
            context.getString(R.string.update),
            context.getString(
                R.string.message_last_update_triggered,
+0 −8
Original line number Diff line number Diff line
@@ -19,15 +19,7 @@
package foundation.e.apps.data.install.wrapper

import foundation.e.apps.data.event.AppEvent
import foundation.e.apps.data.event.EventBus
import javax.inject.Inject

fun interface AppEventDispatcher {
    suspend fun dispatch(event: AppEvent)
}

class AppEventDispatcherImpl @Inject constructor() : AppEventDispatcher {
    override suspend fun dispatch(event: AppEvent) {
        EventBus.invokeEvent(event)
    }
}
Loading