/* * Copyright (C) 2024 Leonard Kugis * Copyright (C) 2023 MURENA SAS * Copyright (C) 2021 E FOUNDATION * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package foundation.e.advancedprivacy.data.repositories import android.content.Context import foundation.e.advancedprivacy.domain.entities.ApplicationDescription import foundation.e.advancedprivacy.domain.entities.FeatureState import foundation.e.advancedprivacy.domain.entities.LocationMode import foundation.e.advancedprivacy.domain.entities.MainFeatures import foundation.e.advancedprivacy.domain.repositories.LocalStateRepository import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import com.google.gson.Gson import com.google.gson.reflect.TypeToken import foundation.e.advancedprivacy.domain.entities.FakeLocationCoordinate class LocalStateRepositoryImpl(context: Context) : LocalStateRepository { companion object { private const val SHARED_PREFS_FILE = "localState" private const val KEY_BLOCK_TRACKERS = "blockTrackers" private const val KEY_IP_SCRAMBLING = "ipScrambling" private const val KEY_FAKE_ALTITUDE = "fakeAltitude" private const val KEY_FAKE_SPEED = "fakeSpeed" private const val KEY_FAKE_BEARING = "fakeBearing" private const val KEY_FAKE_JITTER = "fakeJitter" private const val KEY_FAKE_JITTER_ALTITUDE = "fakeJitterAltitude" private const val KEY_FAKE_JITTER_SPEED = "fakeJitterSpeed" private const val KEY_FAKE_JITTER_BEARING = "fakeJitterBearing" private const val KEY_LOCATION_MODE = "locationMode" private const val KEY_LOCATION_ROUTE = "locationRoute" private const val KEY_LOCATION_ROUTE_LOOP = "locationRouteLoop" private const val KEY_FAKE_LATITUDE = "fakeLatitude" private const val KEY_FAKE_LONGITUDE = "fakeLongitude" private const val KEY_FIRST_BOOT = "firstBoot" private const val KEY_HIDE_WARNING_TRACKERS = "hide_warning_trackers" private const val KEY_HIDE_WARNING_LOCATION = "hide_warning_location" private const val KEY_HIDE_WARNING_IPSCRAMBLING = "hide_warning_ipscrambling" } private val sharedPref = context.getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE) private val _blockTrackers = MutableStateFlow(sharedPref.getBoolean(KEY_BLOCK_TRACKERS, true)) override val blockTrackers = _blockTrackers.asStateFlow() override fun setBlockTrackers(enabled: Boolean) { set(KEY_BLOCK_TRACKERS, enabled) _blockTrackers.update { enabled } } override val areAllTrackersBlocked: MutableStateFlow = MutableStateFlow(false) override var fakeAltitude: Float get() = sharedPref.getFloat(KEY_FAKE_ALTITUDE, 3.0f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_ALTITUDE, value) .apply() } override var fakeSpeed: Float get() = sharedPref.getFloat(KEY_FAKE_SPEED, 1.0f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_SPEED, value) .apply() } override var fakeBearing: Float get() = sharedPref.getFloat(KEY_FAKE_BEARING, 0.0f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_BEARING, value) .apply() } override var fakeJitter: Float get() = sharedPref.getFloat(KEY_FAKE_JITTER, 3.0f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_JITTER, value) .apply() } override var fakeJitterAltitude: Float get() = sharedPref.getFloat(KEY_FAKE_JITTER_ALTITUDE, 3.0f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_JITTER_ALTITUDE, value) .apply() } override var fakeJitterSpeed: Float get() = sharedPref.getFloat(KEY_FAKE_JITTER_SPEED, 0.1f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_JITTER_SPEED, value) .apply() } override var fakeJitterBearing: Float get() = sharedPref.getFloat(KEY_FAKE_JITTER_BEARING, 10.0f) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_JITTER_BEARING, value) .apply() } override var fakeLocation: Pair get() = Pair( // Initial default value is Quezon City sharedPref.getFloat(KEY_FAKE_LATITUDE, 14.6760f), sharedPref.getFloat(KEY_FAKE_LONGITUDE, 121.0437f) ) set(value) { sharedPref.edit() .putFloat(KEY_FAKE_LATITUDE, value.first) .putFloat(KEY_FAKE_LONGITUDE, value.second) .apply() } override var route: List get() { return Gson().fromJson>(sharedPref.getString(KEY_LOCATION_ROUTE, "[]"), object : TypeToken>() {}.type) } set(value) { sharedPref.edit() .putString(KEY_LOCATION_ROUTE, Gson().toJson(value)) .apply() } override var routeLoopEnabled: Boolean get() = sharedPref.getBoolean(KEY_LOCATION_ROUTE_LOOP, false) set(value) { sharedPref.edit() .putBoolean(KEY_LOCATION_ROUTE_LOOP, value) .apply() } private val _locationMode = MutableStateFlow(LocationMode.valueOf(sharedPref.getString(KEY_LOCATION_MODE, LocationMode.REAL_LOCATION.toString()) ?: "REAL_LOCATION")) override val locationMode = _locationMode.asStateFlow() override fun setLocationMode(mode: LocationMode) { sharedPref.edit() .putString(KEY_LOCATION_MODE, mode.toString()) .apply() //set(KEY_LOCATION_MODE, mode.toString()) _locationMode.update { mode } } private val _ipScramblingSetting = MutableStateFlow(sharedPref.getBoolean(KEY_IP_SCRAMBLING, false)) override val ipScramblingSetting = _ipScramblingSetting.asStateFlow() override fun setIpScramblingSetting(enabled: Boolean) { set(KEY_IP_SCRAMBLING, enabled) _ipScramblingSetting.update { enabled } } override val internetPrivacyMode: MutableStateFlow = MutableStateFlow(FeatureState.OFF) private val _startVpnDisclaimer = MutableSharedFlow() override suspend fun emitStartVpnDisclaimer(feature: MainFeatures) { _startVpnDisclaimer.emit(feature) } override val startVpnDisclaimer: SharedFlow = _startVpnDisclaimer private val _otherVpnRunning = MutableSharedFlow() override suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) { _otherVpnRunning.emit(appDesc) } override val otherVpnRunning: SharedFlow = _otherVpnRunning override var firstBoot: Boolean get() = sharedPref.getBoolean(KEY_FIRST_BOOT, true) set(value) = set(KEY_FIRST_BOOT, value) override var hideWarningTrackers: Boolean get() = sharedPref.getBoolean(KEY_HIDE_WARNING_TRACKERS, false) set(value) = set(KEY_HIDE_WARNING_TRACKERS, value) override var hideWarningLocation: Boolean get() = sharedPref.getBoolean(KEY_HIDE_WARNING_LOCATION, false) set(value) = set(KEY_HIDE_WARNING_LOCATION, value) override var hideWarningIpScrambling: Boolean get() = sharedPref.getBoolean(KEY_HIDE_WARNING_IPSCRAMBLING, false) set(value) = set(KEY_HIDE_WARNING_IPSCRAMBLING, value) private fun set(key: String, value: Boolean) { sharedPref.edit().putBoolean(key, value).apply() } }