aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/foundation/e/privacycentralapp/features
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp/features')
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt112
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt3
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt38
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt117
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt60
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsFragment.kt93
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt63
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFeature.kt118
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt72
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsViewModel.kt40
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt56
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt61
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFeature.kt1
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt1
15 files changed, 3 insertions, 834 deletions
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))
// }