diff options
Diffstat (limited to 'app/src/main/java/foundation/e')
21 files changed, 3 insertions, 1340 deletions
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt index 27d6ac4..1553b52 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt @@ -28,7 +28,6 @@ import foundation.e.privacycentralapp.domain.usecases.IpScramblingStateUseCase import foundation.e.privacycentralapp.domain.usecases.TrackersStateUseCase import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase import foundation.e.privacycentralapp.dummy.CityDataSource -import foundation.e.privacycentralapp.dummy.TrackTrackersPrivacyMock import foundation.e.privacycentralapp.features.dashboard.DashBoardViewModelFactory import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyViewModelFactory import foundation.e.privacycentralapp.features.location.FakeLocationViewModelFactory @@ -74,7 +73,6 @@ class DependencyContainer constructor(val app: Application) { private val localStateRepository by lazy { LocalStateRepository(context) } private val trackTrackersPrivacyModule by lazy { TrackTrackersPrivacyModule.getInstance(context) } - private val trackersPrivacyMock by lazy { TrackTrackersPrivacyMock() } // Usecases private val getQuickPrivacyStateUseCase by lazy { GetQuickPrivacyStateUseCase(localStateRepository) diff --git a/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt index 153e0c1..9372a66 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt @@ -18,17 +18,9 @@ package foundation.e.privacycentralapp import android.app.Application -import foundation.e.privacycentralapp.dummy.TrackersDataSource class PrivacyCentralApplication : Application() { // Initialize the dependency container. val dependencyContainer: DependencyContainer by lazy { DependencyContainer(this) } - - override fun onCreate() { - super.onCreate() - - // Inject blocker service in trackers source. - TrackersDataSource.injectBlockerService(dependencyContainer.blockerService) - } } diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt deleted file mode 100644 index 38daeab..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.dummy - -import foundation.e.privacycentralapp.R -import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode -import foundation.e.privacycentralapp.domain.entities.LocationMode -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlin.random.Random - -// ======================================================// -// -// ================ ==== ==== =============== -// ================ ====== ====== ================ -// ==== ======== ======== ==== ==== -// ==== ========= ========= ==== ==== -// ==== ==================== ================ -// ==== ==== ======== ==== =============== -// ==== ==== ==== ==== ==== -// ================ ==== == ==== ==== -// ================ ==== ==== ==== -// -// ======================================================// - -/** - * This whole file acts as a dummy source. All data classes and method implementations - * are not proper ones and are subject to change anytime. - */ - -/** - * Dummmy permission data class. - */ -data class Permission( - val id: Int, - val name: String, - val iconId: Int, - val packagesRequested: Set<String> = emptySet(), - val packagesAllowed: Set<String> = emptySet() -) - -data class Location(val mode: LocationMode, val latitude: Double, val longitude: Double) - -object DummyDataSource { - - const val trackersCount = 77 - private val _activeTrackersCount = MutableStateFlow(10) - val activeTrackersCount = _activeTrackersCount.asStateFlow() - - private val _location = MutableStateFlow(Location(LocationMode.REAL_LOCATION, 0.0, 0.0)) - val location = _location.asStateFlow() - - private val _internetActivityMode = MutableStateFlow(InternetPrivacyMode.REAL_IP) - val internetActivityMode = _internetActivityMode.asStateFlow() - - /** - * Declare dummy permissions with following ids - * - * [0] -> Body sensor - * [1] -> Calendar - * [2] -> Call Logs - * [3] -> Location - */ - val permissions = arrayOf("Body Sensor", "Calendar", "Call Logs", "Location") - - private val permissionIcons = arrayOf( - R.drawable.ic_body_monitor, - R.drawable.ic_calendar, - R.drawable.ic_call, - R.drawable.ic_location - ) - - val packages = arrayOf( - "facebook", - "uber", - "instagram", - "openstreetmap", - "truecaller", - "netflix", - "firefox", - "pubg", - "amazon", - "calendar", - "zohomail", - "privacycentral" - ) - - val _populatedPermissions = MutableStateFlow(fetchPermissions()) - val populatedPermission = _populatedPermissions.asStateFlow() - - private val _appsUsingLocationPerm = - MutableStateFlow(_populatedPermissions.value[3].packagesAllowed) - val appsUsingLocationPerm = _appsUsingLocationPerm.asStateFlow() - - private fun fetchPermissions(): List<Permission> { - val result = mutableListOf<Permission>() - permissions.forEachIndexed { index, permission -> - when (index) { - 0 -> result.add(Permission(index, permission, permissionIcons[index])) - 1 -> { - val randomPackages = getRandomItems(packages, 8) - val grantedPackages = getRandomItems(randomPackages, 3) - result.add( - Permission( - index, - permission, - permissionIcons[index], - randomPackages, - grantedPackages - ) - ) - } - 2 -> { - val randomPackages = getRandomItems(packages, 10) - val grantedPackages = getRandomItems(randomPackages, 9) - result.add( - Permission( - index, - permission, - permissionIcons[index], - randomPackages, - grantedPackages - ) - ) - } - 3 -> { - val randomPackages = getRandomItems(packages, 5) - val grantedPackages = getRandomItems(randomPackages, 3) - result.add( - Permission( - index, - permission, - permissionIcons[index], - randomPackages, - grantedPackages - ) - ) - } - } - } - return result - } - - private fun <T> getRandomItems(data: Array<T>, limit: Int): Set<T> = - getRandomItems(data.toSet(), limit) - - private fun <T> getRandomItems(data: Set<T>, limit: Int): Set<T> { - val randomItems = mutableSetOf<T>() - val localData = data.toMutableList() - repeat(limit) { - val generated = localData.random() - randomItems.add(generated) - localData.remove(generated) - } - return randomItems - } - - fun getPermission(permissionId: Int): Permission = populatedPermission.value[permissionId] - - fun getLocationPermissionApps(): Permission = getPermission(3) - - fun setLocationMode(locationMode: LocationMode, location: Location? = null): Boolean { - when (locationMode) { - LocationMode.REAL_LOCATION -> - _location.value = - Location(LocationMode.REAL_LOCATION, 24.39, 71.80) - LocationMode.RANDOM_LOCATION -> { - requireNotNull(location) { "Custom location should be null" } - _location.value = location - } - LocationMode.SPECIFIC_LOCATION -> { - requireNotNull(location) { "Custom location should be null" } - _location.value = location.copy(mode = LocationMode.SPECIFIC_LOCATION) - } - } - return true - } - - private fun randomLocation(): Location = Location( - LocationMode.RANDOM_LOCATION, - Random.nextDouble(-90.0, 90.0), - Random.nextDouble(-180.0, 180.0) - ) - - fun setInternetPrivacyMode(mode: InternetPrivacyMode): Boolean { - _internetActivityMode.value = mode - return true - } - - fun togglePermission(permissionId: Int, packageName: String, grant: Boolean) { - val allPermissions = _populatedPermissions.value.toMutableList() - val permission: Permission = allPermissions[permissionId].let { permission -> - - val packagesAllowed = permission.packagesAllowed.toMutableSet() - - if (grant) packagesAllowed.add(packageName) - else packagesAllowed.remove(packageName) - - permission.copy(packagesAllowed = packagesAllowed) - } - allPermissions[permissionId] = permission - _populatedPermissions.value = allPermissions - - // Update when permission is toggled for Location - if (permissionId == 3) { - _appsUsingLocationPerm.value = _populatedPermissions.value[permissionId].packagesAllowed - } - } -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/Extensions.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/Extensions.kt deleted file mode 100644 index ab4ba72..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/dummy/Extensions.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.dummy - -import android.content.Context -import foundation.e.privacycentralapp.R -import foundation.e.privacycentralapp.domain.entities.LocationMode - -fun LocationMode.mapToString(context: Context): String = when (this) { - LocationMode.REAL_LOCATION -> context.getString(R.string.real_location_mode) - LocationMode.RANDOM_LOCATION -> context.getString(R.string.random_location_mode) - LocationMode.SPECIFIC_LOCATION -> context.getString(R.string.fake_location_mode) -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt deleted file mode 100644 index 5b1eb9e..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackTrackersPrivacyMock.kt +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.dummy - -import foundation.e.privacymodules.trackers.IBlockTrackersPrivacyModule -import foundation.e.privacymodules.trackers.ITrackTrackersPrivacyModule -import foundation.e.privacymodules.trackers.Tracker - -class TrackTrackersPrivacyMock : - ITrackTrackersPrivacyModule, - IBlockTrackersPrivacyModule { - - private val trackers = listOf( - Tracker(1, "Crashlytics", null), - Tracker(2, label = "Facebook", null) - ) - - override fun getPastDayTrackersCalls(): List<Int> { - return listOf( - 2000, 2300, 130, 2500, 1000, 2000, - 2000, 2300, 130, 2500, 1000, 2000, - 2000, 2300, 130, 2500, 1000, 2000, - 2000, 2300, 130, 2500, 1000, 2000 - ) - } - - override fun getPastDayTrackersCount(): Int { - return 30 - } - - override fun getPastMonthTrackersCalls(): List<Int> { - return listOf( - 20000, 23000, 24130, 12500, 31000, 22000, - 20000, 23000, 24130, 12500, 31000, 22000, - 20000, 23000, 24130, 12500, 31000, 22000, - 20000, 23000, 24130, 12500, 31000, 22000, - 20000, 23000, 24130, 12500, 31000, 22000 - ) - } - - override fun getPastMonthTrackersCount(): Int { - return 43 - } - - override fun getPastYearTrackersCalls(): List<Int> { - return listOf( - 620000, 823000, 424130, 712500, 831000, 922000, - 620000, 823000, 424130, 712500, 831000, 922000 - ) - } - - override fun getPastYearTrackersCount(): Int { - return 46 - } - - override fun getTrackersCount(): Int { - return 72 - } - - override fun getTrackersForApp(appUid: Int): List<Tracker> { - return trackers - } - - private var isBlockingEnabled = false - private val appWhitelist = mutableSetOf<Int>() - private val trackersWhitelist = mutableMapOf<Int, MutableSet<Tracker>>() - - override fun addListener(listener: IBlockTrackersPrivacyModule.Listener) { - TODO("Not yet implemented") - } - - override fun removeListener(listener: IBlockTrackersPrivacyModule.Listener) { - TODO("Not yet implemented") - } - - override fun clearListeners() { - TODO("Not yet implemented") - } - - override fun disableBlocking() {} - - override fun enableBlocking() {} - - override fun getWhiteList(appUid: Int): List<Tracker> { - return trackersWhitelist[appUid]?.toList() ?: emptyList() - } - - override fun getWhiteListedApp(): List<Int> { - return appWhitelist.toList() - } - - override fun isBlockingEnabled(): Boolean { - return isBlockingEnabled - } - - override fun isWhiteListEmpty(): Boolean { - return appWhitelist.isEmpty() && - (trackersWhitelist.isEmpty() || trackersWhitelist.values.all { it.isEmpty() }) - } - - override fun isWhitelisted(appUid: Int): Boolean { - return appUid in appWhitelist - } - - override fun setWhiteListed(tracker: Tracker, appUid: Int, isWhiteListed: Boolean) { - if (appUid !in trackersWhitelist) { - trackersWhitelist[appUid] = mutableSetOf<Tracker>() - } - - if (isWhiteListed) { - trackersWhitelist[appUid]?.add(tracker) - } else { - trackersWhitelist[appUid]?.remove(tracker) - } - } - - override fun setWhiteListed(appUid: Int, isWhiteListed: Boolean) { - if (isWhiteListed) { - appWhitelist.add(appUid) - } else { - appWhitelist.remove(appUid) - } - } -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt deleted file mode 100644 index b6f319c..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.dummy - -import foundation.e.privacycentralapp.R -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import lineageos.blockers.BlockerInterface - -data class TrackedApp(val appName: String, val isEnabled: Boolean, val iconId: Int) - -data class Tracker( - val name: String, - val domain: String? = null, - val ipAddress: String? = null, - val trackedApps: List<TrackedApp> -) - -object TrackersDataSource { - - private lateinit var blockerService: BlockerInterface - - val facebook = TrackedApp("Facebook", true, R.drawable.ic_facebook) - val firefox = TrackedApp("Firefox", true, R.drawable.ic_facebook) - val google = TrackedApp("Google", true, R.drawable.ic_facebook) - val whatsapp = TrackedApp("Whatsapp", true, R.drawable.ic_facebook) - val blisslauncher = TrackedApp("BlissLauncher", true, R.drawable.ic_facebook) - val youtube = TrackedApp("Youtube", true, R.drawable.ic_facebook) - - val crashlytics = Tracker( - "Google Crashlytics", - domain = "|0b|crashlytics|03|com", - trackedApps = listOf(facebook, firefox) - ) - - val facebookAds = Tracker( - "Facebook Analytics", - domain = "|08|facebook|03|com", - trackedApps = listOf(facebook, whatsapp) - ) - val rubiconTracker = Tracker( - "Rubicon Projects", - domain = "|03|ads|0e|rubiconproject|03|com", - trackedApps = listOf(google, blisslauncher, youtube) - ) - val googleAnalytics = Tracker( - "Google Analytics", - domain = "|10|google-analytics|03|com", - trackedApps = listOf(facebook, firefox) - ) - - val _trackers = - MutableStateFlow(listOf(crashlytics, facebookAds, rubiconTracker, googleAnalytics)) - val trackers = _trackers.asStateFlow() - - fun injectBlockerService(blockerInterface: BlockerInterface) { - this.blockerService = blockerInterface - } - - fun getTracker(name: String): Tracker? { - try { - return _trackers.value.first { - it.name == name - } - } catch (e: NoSuchElementException) { - return null - } - } - - fun toggleTracker(tracker: Tracker, enable: Boolean): Boolean { - val result = if (!enable) { - blockerService.blockDomain(tracker.domain) - } else { - blockerService.unblockDomain(tracker.domain) - } - - if (result) { - _trackers.value = _trackers.value.map { - if (it.name == tracker.name) { - it.copy( - trackedApps = it.trackedApps.map { app -> - app.copy(isEnabled = enable) - } - ) - } else it - } - } - return result - } -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt index 8d5c78b..b25e9ed 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt @@ -62,7 +62,6 @@ class DashboardFeature( ) sealed class SingleEvent { - object NavigateToQuickProtectionSingleEvent : SingleEvent() object NavigateToTrackersSingleEvent : SingleEvent() object NavigateToInternetActivityPrivacySingleEvent : SingleEvent() object NavigateToLocationSingleEvent : SingleEvent() @@ -71,11 +70,7 @@ class DashboardFeature( sealed class Action { object InitAction : Action() - object TogglePrivacyAction : Action() - // object ShowQuickPrivacyProtectionInfoAction : Action() - // object ObserveDashboardAction : Action() - // object ShowDashboardAction : Action() object ShowFakeMyLocationAction : Action() object ShowInternetActivityPrivacyAction : Action() object ShowAppsPermissions : Action() @@ -92,25 +87,7 @@ class DashboardFeature( val trackersCount: Int ) : Effect() data class TrackersBlockedUpdatedEffect(val areAllTrackersBlocked: Boolean) : Effect() - - object OpenQuickPrivacyProtectionEffect : Effect() - data class OpenDashboardEffect( - val trackersCount: Int, - val activeTrackersCount: Int, - val totalApps: Int, - val permissionCount: Int, - val appsUsingLocationPerm: Int, - val locationMode: LocationMode, - val internetPrivacyMode: InternetPrivacyMode - ) : Effect() - - object LoadingDashboardEffect : Effect() - data class UpdateActiveTrackersCountEffect(val count: Int) : Effect() - data class UpdateTotalTrackersCountEffect(val count: Int) : Effect() data class UpdateLocationModeEffect(val mode: LocationMode) : Effect() - data class UpdateInternetActivityModeEffect(val mode: InternetPrivacyMode) : Effect() - data class UpdateAppsUsingLocationPermEffect(val apps: Int) : Effect() - object OpenFakeMyLocationEffect : Effect() object OpenInternetActivityPrivacyEffect : Effect() object OpenAppsPermissionsEffect : Effect() @@ -144,50 +121,6 @@ class DashboardFeature( ) is Effect.UpdateLocationModeEffect -> state.copy(locationMode = effect.mode) - /*is Effect.OpenDashboardEffect -> State.DashboardState( - effect.trackersCount, - effect.activeTrackersCount, - effect.totalApps, - effect.permissionCount, - effect.appsUsingLocationPerm, - effect.locationMode, - effect.internetPrivacyMode - ) - Effect.LoadingDashboardEffect -> { - if (state is State.InitialState) { - State.LoadingDashboardState - } else state - } - is Effect.UpdateActiveTrackersCountEffect -> { - if (state is State.DashboardState) { - state.copy(activeTrackersCount = effect.count) - } else state - } - is Effect.UpdateTotalTrackersCountEffect -> { - if (state is State.DashboardState) { - state.copy(trackersCount = effect.count) - } else state - } - is Effect.UpdateInternetActivityModeEffect -> { - if (state is State.DashboardState) { - state.copy(internetPrivacyMode = effect.mode) - } else state - } - is Effect.UpdateLocationModeEffect -> { - if (state is State.DashboardState) { - state.copy(locationMode = effect.mode) - } else state - } - is Effect.UpdateAppsUsingLocationPermEffect -> if (state is State.DashboardState) { - state.copy(appsUsingLocationPerm = effect.apps) - } else state - - Effect.OpenFakeMyLocationEffect -> state - Effect.OpenAppsPermissionsEffect -> state - Effect.OpenInternetActivityPrivacyEffect -> state - Effect.OpenTrackersEffect -> state - */ - else -> state } }, @@ -223,51 +156,6 @@ class DashboardFeature( Effect.UpdateLocationModeEffect(it) } ) - /* - Action.ObserveDashboardAction -> { - merge( - TrackersDataSource.trackers.map { - var activeTrackersCount: Int = 0 - outer@ for (tracker in it) { - for (app in tracker.trackedApps) { - if (!app.isEnabled) { - continue@outer - } - } - activeTrackersCount++ - } - Effect.UpdateActiveTrackersCountEffect(activeTrackersCount) - }, - TrackersDataSource.trackers.map { - Effect.UpdateTotalTrackersCountEffect(it.size) - }, - DummyDataSource.appsUsingLocationPerm.map { - Effect.UpdateAppsUsingLocationPermEffect(it.size) - }, - DummyDataSource.location.map { - Effect.UpdateLocationModeEffect(it.mode) - }, - DummyDataSource.internetActivityMode.map { - Effect.UpdateInternetActivityModeEffect(it) - } - ) - Action.ShowQuickPrivacyProtectionInfoAction -> flowOf( - Effect.OpenQuickPrivacyProtectionEffect - ) - Action.ShowDashboardAction -> flow { - emit(Effect.LoadingDashboardEffect) - emit( - Effect.OpenDashboardEffect( - DummyDataSource.trackersCount, - DummyDataSource.activeTrackersCount.value, - DummyDataSource.packages.size, - DummyDataSource.permissions.size, - DummyDataSource.appsUsingLocationPerm.value.size, - DummyDataSource.location.value.mode, - DummyDataSource.internetActivityMode.value - ) - ) - }*/ Action.ShowFakeMyLocationAction -> flowOf(Effect.OpenFakeMyLocationEffect) Action.ShowAppsPermissions -> flowOf(Effect.OpenAppsPermissionsEffect) Action.ShowInternetActivityPrivacyAction -> flowOf( diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt index 75525f5..a7c14ad 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt @@ -96,8 +96,6 @@ class DashboardFragment : } lifecycleScope.launchWhenStarted { viewModel.submitAction(DashboardFeature.Action.InitAction) - // viewModel.submitAction(DashboardFeature.Action.ShowDashboardAction) - // viewModel.submitAction(DashboardFeature.Action.ObserveDashboardAction) } } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt index a9482db..183e400 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt @@ -71,8 +71,6 @@ class InternetPrivacyFeature( } sealed class SingleEvent { - object RealIPSelectedEvent : SingleEvent() - object HiddenIPSelectedEvent : SingleEvent() data class StartAndroidVpnActivityEvent(val intent: Intent) : SingleEvent() data class ErrorEvent(val error: String) : SingleEvent() } @@ -137,7 +135,6 @@ class InternetPrivacyFeature( action is Action.LoadInternetModeAction -> merge( getQuickPrivacyStateUseCase.quickPrivacyEnabledFlow.map { Effect.QuickPrivacyUpdatedEffect(it) }, ipScramblingStateUseCase.internetPrivacyMode.map { Effect.ModeUpdatedEffect(it) }.shareIn(scope = coroutineScope, started = SharingStarted.Lazily, replay = 0), - // flowOf(Effect.ModeUpdatedEffect(InternetPrivacyMode.REAL_IP)), appListUseCase.getAppsUsingInternet().map { apps -> if (ipScramblerModule.appList.isEmpty()) { ipScramblerModule.appList = diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt index b1dc938..a7869ce 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt @@ -57,9 +57,6 @@ class FakeLocationFeature( ) sealed class SingleEvent { - object RandomLocationSelectedEvent : SingleEvent() - object RealLocationSelectedEvent : SingleEvent() - object SpecificLocationSavedEvent : SingleEvent() data class LocationUpdatedEvent(val location: Location?) : SingleEvent() data class ErrorEvent(val error: String) : SingleEvent() } @@ -67,10 +64,6 @@ class FakeLocationFeature( sealed class Action { object Init : Action() object LeaveScreen : Action() - - // Action which is triggered everytime the location is updated. - // data class UpdateLocationAction(val latLng: LatLng) : Action() - object UseRealLocationAction : Action() object UseRandomLocationAction : Action() data class SetSpecificLocationAction( @@ -112,7 +105,6 @@ class FakeLocationFeature( specificLatitude = effect.latitude, specificLongitude = effect.longitude ) - // is Effect.LocationUpdatedEffect -> state.copy(currentLocation = effect.location) Effect.QuickPrivacyDisabledWarningEffect -> state.copy(forceRefresh = !state.forceRefresh) else -> state } @@ -127,37 +119,7 @@ class FakeLocationFeature( emit(Effect.LocationModeUpdatedEffect(mode = mode, latitude = lat, longitude = lon)) }, fakeLocationStateUseCase.currentLocation.map { Effect.LocationUpdatedEffect(it) } - - // callbackFlow { - // val listener = object : LocationListener { - // override fun onLocationChanged(location: Location) { - // Log.e("DebugLoc", "onLocationChanged $location") - // offer(Effect.LocationUpdatedEffect(location)) - // } - // - // override fun onProviderEnabled(provider: String?) { - // Log.e("DebugLoc", "ProvuderEnabled: $provider") - // } - // - // override fun onProviderDisabled(provider: String?) { - // Log.e("DebugLoc", "ProvuderDisabled: $provider") - // } - // } - // - // fakeLocationStateUseCase.requestLocationUpdates(listener) - // // TODO: when is awaitClose called ? - // awaitClose { fakeLocationStateUseCase.removeUpdates(listener) } - // } - ) - - // is Action.UpdateLocationAction -> flowOf( - // Effect.LocationUpdatedEffect( - // action.latLng.latitude, - // action.latLng.longitude - // ) - // ) - is Action.LeaveScreen -> { fakeLocationStateUseCase.stopListeningLocation() flowOf(Effect.NoEffect) diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt index ed7b9be..60b9bd9 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt @@ -24,7 +24,6 @@ import android.os.Bundle import android.text.Editable import android.util.Log import android.view.View -import android.widget.ImageView import android.widget.Toast import androidx.annotation.NonNull import androidx.core.view.isVisible @@ -35,10 +34,6 @@ import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout.END_ICON_CUSTOM import com.google.android.material.textfield.TextInputLayout.END_ICON_NONE -import com.mapbox.android.core.location.LocationEngineCallback -import com.mapbox.android.core.location.LocationEngineResult -import com.mapbox.android.core.permissions.PermissionsListener -import com.mapbox.android.core.permissions.PermissionsManager import com.mapbox.mapboxsdk.Mapbox import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.geometry.LatLng @@ -67,11 +62,9 @@ import kotlinx.coroutines.launch class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location), - MVIView<FakeLocationFeature.State, FakeLocationFeature.Action>, - PermissionsListener { + MVIView<FakeLocationFeature.State, Action> { private var isCameraMoved: Boolean = false - private lateinit var permissionsManager: PermissionsManager private val dependencyContainer: DependencyContainer by lazy { (this.requireActivity().application as PrivacyCentralApplication).dependencyContainer @@ -85,58 +78,12 @@ class FakeLocationFragment : private var mapboxMap: MapboxMap? = null private var locationComponent: LocationComponent? = null - private var hoveringMarker: ImageView? = null private var inputJob: Job? = null - private var displayedLocation: Pair<Float, Float>? = null - - // Callback which updates the map in realtime. - private val locationChangeCallback: LocationEngineCallback<LocationEngineResult> = - object : LocationEngineCallback<LocationEngineResult> { - override fun onSuccess(result: LocationEngineResult?) { - result?.lastLocation?.let { - displayedLocation = it.latitude.toFloat() to it.longitude.toFloat() - mapboxMap?.locationComponent?.forceLocationUpdate( - LocationUpdate.Builder().location(it).animationDuration(100) - .build() - ) - if (!isCameraMoved) { - mapboxMap?.animateCamera( - CameraUpdateFactory.newLatLng( - LatLng( - it.latitude, - it.longitude - ) - ) - ) - } - // Only update location when location mode is set to real location or random location. - // It basically triggers a UI update. - // if (viewModel.fakeLocationFeature.state.value.location.mode != LocationMode.SPECIFIC_LOCATION) { - // viewModel.submitAction( - // FakeLocationFeature.Action.UpdateLocationAction( - // LatLng( - // it.latitude, - // it.longitude - // ) - // ) - // ) - // } - } - } - - override fun onFailure(exception: Exception) { - Log.e(TAG, "${exception.message}") - } - } - companion object { private const val DEBOUNCE_PERIOD = 1000L - private const val TAG = "FakeLocationFragment" private const val DEFAULT_INTERVAL_IN_MILLISECONDS = 1000L - private const val DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 5 - private const val DROPPED_MARKER_LAYER_ID = "DROPPED_MARKER_LAYER_ID" } override fun onCreate(savedInstanceState: Bundle?) { @@ -230,7 +177,6 @@ class FakeLocationFragment : LatLng(lat.toDouble(), lon.toDouble()) ) ) - // viewModel.submitAction(Action.SetSpecificLocationAction(lat, lon)) } } catch (e: NumberFormatException) { } @@ -257,17 +203,6 @@ class FakeLocationFragment : ) } } - - // binding.mapView.addOnTouchListener { _, event -> - // //mapboxMap.addOnCameraMoveStartedListener { - // // Show marker when user starts to move across the map. - // if (event.action == ACTION_DOWN && binding.mapView.isEnabled) { - // hoveringMarker?.visibility = View.VISIBLE - // isCameraMoved = true - // } - // binding.mapView.onTouchEvent(event) - // } - binding.edittextLatitude.addTextChangedListener( afterTextChanged = getCoordinatesAfterTextChanged( binding.textlayoutLatitude, @@ -328,18 +263,6 @@ class FakeLocationFragment : .build() locationComponent?.forceLocationUpdate(locationUpdate) - // if (binding.mapView.isEnabled && !isCameraMoved) { - // binding.mapView.isEnabled = false - // mapboxMap?.moveCamera( - // CameraUpdateFactory.newLatLng( - // LatLng( - // location.latitude, - // location.longitude - // ) - // ) - // ) - // isCameraMoved = false - // binding.mapView.isEnabled = true if (!binding.mapView.isEnabled) { binding.mapLoader.isVisible = false binding.mapOverlay.isVisible = false @@ -361,7 +284,6 @@ class FakeLocationFragment : @SuppressLint("MissingPermission") private fun enableLocationPlugin(@NonNull loadedMapStyle: Style) { // Check if permissions are enabled and if not request - // if (PermissionsManager.areLocationPermissionsGranted(requireContext())) { locationComponent = mapboxMap?.locationComponent locationComponent?.activateLocationComponent( LocationComponentActivationOptions.builder( @@ -371,20 +293,6 @@ class FakeLocationFragment : locationComponent?.isLocationComponentEnabled = true locationComponent?.cameraMode = CameraMode.NONE locationComponent?.renderMode = RenderMode.NORMAL - // //locationComponent.locationEngine?.let { - // it.requestLocationUpdates( - // LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS) - // .setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY) - // .setMaxWaitTime(DEFAULT_MAX_WAIT_TIME).build(), - // locationChangeCallback, - // Looper.getMainLooper() - // ) - // it.getLastLocation(locationChangeCallback) - // } - // } else { - // permissionsManager = PermissionsManager(this) - // permissionsManager.requestLocationPermissions(requireActivity()) - // } } override fun onStart() { @@ -418,27 +326,4 @@ class FakeLocationFragment : super.onDestroyView() binding.mapView.onDestroy() } - - override fun onExplanationNeeded(permissionsToExplain: MutableList<String>?) { - Toast.makeText( - requireContext(), - R.string.user_location_permission_explanation, - Toast.LENGTH_LONG - ).show() - } - - override fun onPermissionResult(granted: Boolean) { - if (granted) { - val style = mapboxMap?.style - if (style != null) { - enableLocationPlugin(style) - } - } else { - Toast.makeText( - requireContext(), - R.string.user_location_permission_not_granted, - Toast.LENGTH_LONG - ).show() - } - } } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt deleted file mode 100644 index 4905dca..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.permissions - -import android.annotation.SuppressLint -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Switch -import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView -import foundation.e.privacycentralapp.R - -class PermissionAppsAdapter( - private val dataSet: List<Pair<String, Boolean>>, - private val listener: (String, Boolean) -> Unit -) : - RecyclerView.Adapter<PermissionAppsAdapter.PermissionViewHolder>() { - - class PermissionViewHolder(view: View) : RecyclerView.ViewHolder(view) { - val appName: TextView = view.findViewById(R.id.app_title) - - @SuppressLint("UseSwitchCompatOrMaterialCode") - val togglePermission: Switch = view.findViewById(R.id.toggle) - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PermissionViewHolder { - val view = LayoutInflater.from(parent.context) - .inflate(R.layout.item_app_toggle, parent, false) - val holder = PermissionViewHolder(view) - holder.togglePermission.setOnCheckedChangeListener { _, isChecked -> - listener(dataSet[holder.adapterPosition].first, isChecked) - } - view.findViewById<Switch>(R.id.toggle) - return holder - } - - override fun onBindViewHolder(holder: PermissionViewHolder, position: Int) { - val permission = dataSet[position] - holder.appName.text = permission.first - holder.togglePermission.isChecked = permission.second - } - - override fun getItemCount(): Int = dataSet.size -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsFragment.kt deleted file mode 100644 index 72d8b0c..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsFragment.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.permissions - -import android.os.Bundle -import android.widget.TextView -import android.widget.Toast -import androidx.fragment.app.viewModels -import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import foundation.e.flowmvi.MVIView -import foundation.e.privacycentralapp.R -import foundation.e.privacycentralapp.common.NavToolbarFragment -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect - -class PermissionAppsFragment : - NavToolbarFragment(R.layout.fragment_permission_apps), - MVIView<PermissionsFeature.State, PermissionsFeature.Action> { - - private val viewModel: PermissionsViewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - lifecycleScope.launchWhenStarted { - viewModel.permissionsFeature.takeView(this, this@PermissionAppsFragment) - } - lifecycleScope.launchWhenStarted { - viewModel.permissionsFeature.singleEvents.collect { event -> - when (event) { - is PermissionsFeature.SingleEvent.ErrorEvent -> displayToast(event.error) - } - } - } - lifecycleScope.launchWhenStarted { - viewModel.submitAction( - PermissionsFeature.Action.LoadPermissionApps( - requireArguments().getInt( - "PERMISSION_ID" - ) - ) - ) - } - } - - private fun displayToast(message: String) { - Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT) - .show() - } - - override fun getTitle(): String = getString(R.string.apps_permissions) - - override fun render(state: PermissionsFeature.State) { - state.currentPermission?.let { permission -> - view?.findViewById<RecyclerView>(R.id.recylcer_view_permission_apps)?.apply { - val listOfPackages = mutableListOf<Pair<String, Boolean>>() - permission.packagesRequested.forEach { - listOfPackages.add(it to permission.packagesAllowed.contains(it)) - } - layoutManager = LinearLayoutManager(requireContext()) - setHasFixedSize(true) - adapter = PermissionAppsAdapter(listOfPackages) { packageName, grant -> - viewModel.submitAction( - PermissionsFeature.Action.TogglePermissionAction( - packageName, - grant - ) - ) - } - } - view?.findViewById<TextView>(R.id.permission_control)?.text = - getString(R.string.apps_access_to_permission, permission.name) - } - } - - override fun actions(): Flow<PermissionsFeature.Action> = viewModel.actions -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt deleted file mode 100644 index 330a1ac..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.permissions - -import android.content.Context -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView -import foundation.e.privacycentralapp.R -import foundation.e.privacycentralapp.dummy.Permission - -class PermissionsAdapter( - private val context: Context, - private val dataSet: List<Permission>, - private val listener: (Int) -> Unit -) : - RecyclerView.Adapter<PermissionsAdapter.PermissionViewHolder>() { - - class PermissionViewHolder(view: View) : RecyclerView.ViewHolder(view) { - val nameView: TextView = view.findViewById(R.id.permission_title) - val permissionCountView: TextView = view.findViewById(R.id.permission_count) - val permissionIcon: ImageView = view.findViewById(R.id.permission_icon) - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PermissionViewHolder { - val view = LayoutInflater.from(parent.context) - .inflate(R.layout.item_permission, parent, false) - val holder = PermissionViewHolder(view) - view.setOnClickListener { listener(holder.adapterPosition) } - return holder - } - - override fun onBindViewHolder(holder: PermissionViewHolder, position: Int) { - val permission = dataSet[position] - holder.nameView.text = permission.name - holder.permissionCountView.text = context.getString( - R.string.apps_allowed, - permission.packagesAllowed.size, - permission.packagesRequested.size - ) - holder.permissionIcon.setImageResource(permission.iconId) - } - - override fun getItemCount(): Int = dataSet.size -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFeature.kt deleted file mode 100644 index d095f00..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFeature.kt +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.permissions - -import android.util.Log -import foundation.e.flowmvi.Actor -import foundation.e.flowmvi.Reducer -import foundation.e.flowmvi.SingleEventProducer -import foundation.e.flowmvi.feature.BaseFeature -import foundation.e.privacycentralapp.dummy.DummyDataSource -import foundation.e.privacycentralapp.dummy.Permission -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.map - -// Define a state machine for Internet privacy feature -class PermissionsFeature( - initialState: State, - coroutineScope: CoroutineScope, - reducer: Reducer<State, Effect>, - actor: Actor<State, Action, Effect>, - singleEventProducer: SingleEventProducer<State, Action, Effect, SingleEvent> -) : BaseFeature<PermissionsFeature.State, PermissionsFeature.Action, PermissionsFeature.Effect, PermissionsFeature.SingleEvent>( - initialState, - actor, - reducer, - coroutineScope, - { message -> Log.d("PermissionsFeature", message) }, - singleEventProducer -) { - data class State( - val permissions: List<Permission> = emptyList(), - val currentPermission: Permission? = null - ) - - sealed class SingleEvent { - data class ErrorEvent(val error: String) : SingleEvent() - } - - sealed class Action { - object ObservePermissions : Action() - data class LoadPermissionApps(val id: Int) : Action() - data class TogglePermissionAction( - val packageName: String, - val grant: Boolean - ) : Action() - } - - sealed class Effect { - data class PermissionsLoadedEffect(val permissions: List<Permission>) : Effect() - data class PermissionLoadedEffect(val permission: Permission) : Effect() - object PermissionToggledEffect : Effect() - data class ErrorEffect(val message: String) : Effect() - } - - companion object { - fun create( - initialState: State = State(), - coroutineScope: CoroutineScope - ) = PermissionsFeature( - initialState, coroutineScope, - reducer = { state, effect -> - when (effect) { - is Effect.PermissionsLoadedEffect -> State(effect.permissions) - is Effect.PermissionLoadedEffect -> state.copy(currentPermission = effect.permission) - is Effect.ErrorEffect -> state - Effect.PermissionToggledEffect -> state - } - }, - actor = { state, action -> - when (action) { - Action.ObservePermissions -> DummyDataSource.populatedPermission.map { - Effect.PermissionsLoadedEffect(it) - } - is Action.LoadPermissionApps -> flowOf( - Effect.PermissionLoadedEffect( - DummyDataSource.getPermission(action.id) - ) - ) - - is Action.TogglePermissionAction -> { - if (state.currentPermission != null) { - DummyDataSource.togglePermission( - state.currentPermission.id, - action.packageName, - action.grant - ) - flowOf(Effect.PermissionToggledEffect) - } else { - flowOf(Effect.ErrorEffect("Can't update permission")) - } - } - } - }, - singleEventProducer = { _, _, effect -> - when (effect) { - is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message) - else -> null - } - } - ) - } -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt deleted file mode 100644 index be84e31..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.permissions - -import android.os.Bundle -import android.view.View -import androidx.core.os.bundleOf -import androidx.fragment.app.add -import androidx.fragment.app.commit -import androidx.fragment.app.viewModels -import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import foundation.e.flowmvi.MVIView -import foundation.e.privacycentralapp.R -import foundation.e.privacycentralapp.common.NavToolbarFragment -import kotlinx.coroutines.flow.Flow - -class PermissionsFragment : - NavToolbarFragment(R.layout.fragment_permissions), - MVIView<PermissionsFeature.State, PermissionsFeature.Action> { - - private val viewModel: PermissionsViewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - lifecycleScope.launchWhenStarted { - viewModel.permissionsFeature.takeView(this, this@PermissionsFragment) - } - lifecycleScope.launchWhenStarted { - viewModel.submitAction(PermissionsFeature.Action.ObservePermissions) - } - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - } - - override fun getTitle(): String = getString(R.string.apps_permissions) - - override fun render(state: PermissionsFeature.State) { - view?.findViewById<RecyclerView>(R.id.recylcer_view_permissions)?.apply { - layoutManager = LinearLayoutManager(requireContext()) - setHasFixedSize(true) - adapter = PermissionsAdapter(requireContext(), state.permissions) { permissionId -> - requireActivity().supportFragmentManager.commit { - val bundle = bundleOf("PERMISSION_ID" to permissionId) - add<PermissionAppsFragment>(R.id.container, args = bundle) - setReorderingAllowed(true) - addToBackStack("permissions") - } - } - } - } - - override fun actions(): Flow<PermissionsFeature.Action> = viewModel.actions -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsViewModel.kt deleted file mode 100644 index fc50c39..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsViewModel.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.permissions - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.asSharedFlow -import kotlinx.coroutines.launch - -class PermissionsViewModel : ViewModel() { - - private val _actions = MutableSharedFlow<PermissionsFeature.Action>() - val actions = _actions.asSharedFlow() - - val permissionsFeature: PermissionsFeature by lazy { - PermissionsFeature.create(coroutineScope = viewModelScope) - } - - fun submitAction(action: PermissionsFeature.Action) { - viewModelScope.launch { - _actions.emit(action) - } - } -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt deleted file mode 100644 index cef069e..0000000 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 <https://www.gnu.org/licenses/>. - */ - -package foundation.e.privacycentralapp.features.trackers - -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.recyclerview.widget.RecyclerView -import foundation.e.privacycentralapp.R -import foundation.e.privacycentralapp.dummy.Tracker - -class TrackersAdapter( - private var dataSet: List<Tracker> = emptyList(), - private val listener: (Tracker) -> Unit -) : - RecyclerView.Adapter<TrackersAdapter.TrackerViewHolder>() { - - class TrackerViewHolder(view: View) : RecyclerView.ViewHolder(view) { - val titleView: TextView = view as TextView - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackerViewHolder { - val view = LayoutInflater.from(parent.context) - .inflate(R.layout.item_list_tracker, parent, false) - val holder = TrackerViewHolder(view) - holder.titleView.setOnClickListener { listener(dataSet[holder.adapterPosition]) } - return holder - } - - override fun onBindViewHolder(holder: TrackerViewHolder, position: Int) { - val tracker = dataSet[position] - holder.titleView.text = tracker.name - } - - override fun getItemCount(): Int = dataSet.size - - fun setData(data: List<Tracker>) { - this.dataSet = data - } -} diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt index 81edea8..9bd2c7a 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt @@ -25,9 +25,8 @@ import foundation.e.flowmvi.feature.BaseFeature import foundation.e.privacycentralapp.domain.usecases.AppListUseCase import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase import foundation.e.privacycentralapp.domain.usecases.TrackersStatisticsUseCase -import foundation.e.privacycentralapp.dummy.Tracker -import foundation.e.privacycentralapp.dummy.TrackersDataSource import foundation.e.privacymodules.permissions.data.ApplicationDescription +import foundation.e.privacymodules.trackers.Tracker import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @@ -65,20 +64,11 @@ class TrackersFeature( sealed class SingleEvent { data class ErrorEvent(val error: String) : SingleEvent() data class OpenAppDetailsEvent(val appDesc: ApplicationDescription) : SingleEvent() - object BlockerErrorEvent : SingleEvent() } sealed class Action { object InitAction : Action() data class ClickAppAction(val packageName: String) : Action() - - object ObserveTrackers : Action() - data class SetSelectedTracker(val tracker: Tracker) : Action() - data class ToggleTrackerAction( - val tracker: Tracker, - val grant: Boolean - ) : Action() - data class ObserveTracker(val tracker: String?) : Action() } sealed class Effect { @@ -95,11 +85,7 @@ class TrackersFeature( ) : Effect() data class OpenAppDetailsEffect(val appDesc: ApplicationDescription) : Effect() object QuickPrivacyDisabledWarningEffect : Effect() - data class TrackersLoadedEffect(val trackers: List<Tracker>) : Effect() - data class TrackerSelectedEffect(val tracker: Tracker) : Effect() - data class TrackerToggleEffect(val result: Boolean) : Effect() data class ErrorEffect(val message: String) : Effect() - data class TrackerLoadedEffect(val tracker: Tracker) : Effect() } companion object { @@ -123,15 +109,7 @@ class TrackersFeature( ) is Effect.AvailableAppsListEffect -> state.copy(apps = effect.apps) - is Effect.TrackersLoadedEffect -> State() - is Effect.TrackerSelectedEffect -> state.copy(currentSelectedTracker = effect.tracker) is Effect.ErrorEffect -> state - is Effect.TrackerToggleEffect -> { - state - } - is Effect.TrackerLoadedEffect -> { - state.copy(currentSelectedTracker = effect.tracker) - } else -> state } }, @@ -164,49 +142,12 @@ class TrackersFeature( } ?: run { Effect.ErrorEffect("Can't find back app.") } } else Effect.QuickPrivacyDisabledWarningEffect ) - Action.ObserveTrackers -> TrackersDataSource.trackers.map { - Effect.TrackersLoadedEffect( - it - ) - } - is Action.SetSelectedTracker -> flowOf( - Effect.TrackerSelectedEffect( - action.tracker - ) - ) - - is Action.ToggleTrackerAction -> { - if (state.currentSelectedTracker != null) { - val result = TrackersDataSource.toggleTracker( - action.tracker, - action.grant - ) - flowOf(Effect.TrackerToggleEffect(result)) - } else { - flowOf(Effect.ErrorEffect("Can't toggle tracker")) - } - } - is Action.ObserveTracker -> { - if (action.tracker == null) { - flowOf(Effect.ErrorEffect("Null tracker id passed")) - } else { - val tracker = TrackersDataSource.getTracker(action.tracker) - if (tracker != null) { - flowOf(Effect.TrackerLoadedEffect(tracker)) - } else { - flowOf(Effect.ErrorEffect("Can't find tracker with name ${action.tracker}")) - } - } - } } }, singleEventProducer = { _, _, effect -> when (effect) { is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message) is Effect.OpenAppDetailsEffect -> SingleEvent.OpenAppDetailsEvent(effect.appDesc) - is Effect.TrackerToggleEffect -> { - if (!effect.result) SingleEvent.BlockerErrorEvent else null - } Effect.QuickPrivacyDisabledWarningEffect -> SingleEvent.ErrorEvent("Enabled Quick Privacy to use functionalities") else -> null } diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt index a62ed16..14ee921 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt @@ -28,7 +28,6 @@ import foundation.e.privacymodules.trackers.Tracker import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge // Define a state machine for Tracker feature. diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt index f0b0aef..2fab8cf 100644 --- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt +++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt @@ -92,6 +92,7 @@ class AppTrackersFragment : super.onViewCreated(view, savedInstanceState) binding = ApptrackersFragmentBinding.bind(view) + // TODO: crash sqlite ? // binding.blockAllToggle.setOnCheckedChangeListener { _, isChecked -> // viewModel.submitAction(Action.BlockAllToggleAction(isChecked)) // } |