/* * Copyright (C) 2023 MURENA SAS * Copyright (C) 2021 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 . */ package foundation.e.advancedprivacy import android.app.Application import android.content.Context import android.os.Process import androidx.lifecycle.DEFAULT_ARGS_KEY import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewmodel.CreationExtras import foundation.e.advancedprivacy.common.WarningDialog import foundation.e.advancedprivacy.data.repositories.AppListsRepository import foundation.e.advancedprivacy.data.repositories.LocalStateRepository import foundation.e.advancedprivacy.data.repositories.TrackersRepository import foundation.e.advancedprivacy.domain.usecases.AppListUseCase import foundation.e.advancedprivacy.domain.usecases.FakeLocationStateUseCase import foundation.e.advancedprivacy.domain.usecases.GetQuickPrivacyStateUseCase import foundation.e.advancedprivacy.domain.usecases.IpScramblingStateUseCase import foundation.e.advancedprivacy.domain.usecases.ShowFeaturesWarningUseCase import foundation.e.advancedprivacy.domain.usecases.TrackersStateUseCase import foundation.e.advancedprivacy.domain.usecases.TrackersStatisticsUseCase import foundation.e.advancedprivacy.dummy.CityDataSource import foundation.e.advancedprivacy.features.dashboard.DashboardViewModel import foundation.e.advancedprivacy.features.internetprivacy.InternetPrivacyViewModel import foundation.e.advancedprivacy.features.location.FakeLocationViewModel import foundation.e.advancedprivacy.features.trackers.TrackersViewModel import foundation.e.advancedprivacy.features.trackers.apptrackers.AppTrackersFragmentArgs import foundation.e.advancedprivacy.features.trackers.apptrackers.AppTrackersViewModel import foundation.e.privacymodules.fakelocation.FakeLocationModule import foundation.e.privacymodules.ipscrambler.IIpScramblerModule import foundation.e.privacymodules.ipscrambler.IpScramblerModule import foundation.e.privacymodules.permissions.PermissionsPrivacyModule import foundation.e.privacymodules.permissions.data.ApplicationDescription import foundation.e.privacymodules.permissions.data.ProfileType import foundation.e.privacymodules.trackers.api.BlockTrackersPrivacyModule import foundation.e.privacymodules.trackers.api.TrackTrackersPrivacyModule import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope /** * Simple container to hold application wide dependencies. * */ @OptIn(DelicateCoroutinesApi::class) class DependencyContainer(val app: Application) { val context: Context by lazy { app.applicationContext } // Drivers private val fakeLocationModule: FakeLocationModule by lazy { FakeLocationModule(app.applicationContext) } private val permissionsModule by lazy { PermissionsPrivacyModule(app.applicationContext) } private val ipScramblerModule: IIpScramblerModule by lazy { IpScramblerModule(app.applicationContext) } private val appDesc by lazy { ApplicationDescription( packageName = context.packageName, uid = Process.myUid(), label = context.resources.getString(R.string.app_name), icon = null, profileId = -1, profileType = ProfileType.MAIN ) } private val blockTrackersPrivacyModule by lazy { BlockTrackersPrivacyModule.getInstance(context) } private val trackTrackersPrivacyModule by lazy { TrackTrackersPrivacyModule.getInstance(context) } // Repositories private val localStateRepository by lazy { LocalStateRepository(context) } private val trackersRepository by lazy { TrackersRepository(context) } private val appListsRepository by lazy { AppListsRepository(permissionsModule, context, GlobalScope) } // Usecases val getQuickPrivacyStateUseCase by lazy { GetQuickPrivacyStateUseCase(localStateRepository) } private val ipScramblingStateUseCase by lazy { IpScramblingStateUseCase( ipScramblerModule, permissionsModule, appDesc, localStateRepository, appListsRepository, GlobalScope ) } private val appListUseCase = AppListUseCase(appListsRepository) val trackersStatisticsUseCase by lazy { TrackersStatisticsUseCase(trackTrackersPrivacyModule, blockTrackersPrivacyModule, appListsRepository, context.resources) } val trackersStateUseCase by lazy { TrackersStateUseCase(blockTrackersPrivacyModule, trackTrackersPrivacyModule, localStateRepository, trackersRepository, appListsRepository, GlobalScope) } private val fakeLocationStateUseCase by lazy { FakeLocationStateUseCase( fakeLocationModule, permissionsModule, localStateRepository, CityDataSource, appDesc, context, GlobalScope ) } val showFeaturesWarningUseCase by lazy { ShowFeaturesWarningUseCase(localStateRepository = localStateRepository) } val viewModelsFactory by lazy { ViewModelsFactory( getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase, trackersStatisticsUseCase = trackersStatisticsUseCase, trackersStateUseCase = trackersStateUseCase, fakeLocationStateUseCase = fakeLocationStateUseCase, ipScramblerModule = ipScramblerModule, ipScramblingStateUseCase = ipScramblingStateUseCase, appListUseCase = appListUseCase ) } // Background fun initBackgroundSingletons() { trackersStateUseCase ipScramblingStateUseCase fakeLocationStateUseCase UpdateTrackersWorker.periodicUpdate(context) WarningDialog.startListening( showFeaturesWarningUseCase, GlobalScope, context ) Widget.startListening( context, getQuickPrivacyStateUseCase, trackersStatisticsUseCase, ) Notifications.startListening( context, getQuickPrivacyStateUseCase, permissionsModule, GlobalScope ) } } @Suppress("LongParameterList") class ViewModelsFactory( private val getQuickPrivacyStateUseCase: GetQuickPrivacyStateUseCase, private val trackersStatisticsUseCase: TrackersStatisticsUseCase, private val trackersStateUseCase: TrackersStateUseCase, private val fakeLocationStateUseCase: FakeLocationStateUseCase, private val ipScramblerModule: IIpScramblerModule, private val ipScramblingStateUseCase: IpScramblingStateUseCase, private val appListUseCase: AppListUseCase ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class, extras: CreationExtras): T { return when (modelClass) { AppTrackersViewModel::class.java -> { val app = extras[DEFAULT_ARGS_KEY]?.let { appListUseCase.getApp(AppTrackersFragmentArgs.fromBundle(it).appUid) } ?: appListUseCase.dummySystemApp AppTrackersViewModel( app = app, trackersStateUseCase = trackersStateUseCase, trackersStatisticsUseCase = trackersStatisticsUseCase, getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase ) } TrackersViewModel::class.java -> TrackersViewModel( trackersStatisticsUseCase = trackersStatisticsUseCase ) FakeLocationViewModel::class.java -> FakeLocationViewModel( fakeLocationStateUseCase = fakeLocationStateUseCase ) InternetPrivacyViewModel::class.java -> InternetPrivacyViewModel( ipScramblerModule = ipScramblerModule, getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase, ipScramblingStateUseCase = ipScramblingStateUseCase, appListUseCase = appListUseCase ) DashboardViewModel::class.java -> DashboardViewModel( getPrivacyStateUseCase = getQuickPrivacyStateUseCase, trackersStatisticsUseCase = trackersStatisticsUseCase ) else -> throw IllegalArgumentException("Unknown class $modelClass") } as T } }