summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2022-11-06 18:19:17 +0000
committerGuillaume Jacquart <guillaume.jacquart@hoodbrains.com>2022-11-06 18:19:17 +0000
commit99b27efb59ba642bfca0c6fbabfaa2c6631e15b9 (patch)
treec55aed6119dff29a84d7120bedf88e2df1775597
parent9701ef06a47560ca429f1e7fffd0958b376ec628 (diff)
parentfdeecefd34c00b225bd58f6cc7135a95e21728f1 (diff)
Merge branch '5561-name_the_vpn_already_running' into 'main'
5561: display name of other VPNrunning always on. See merge request e/os/advanced-privacy!96
-rw-r--r--app/build.gradle9
-rw-r--r--app/src/androidTest/java/foundation/e/privacycentralapp/ExampleInstrumentedTest.kt39
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt26
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt5
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/TextViewHelpers.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/extensions/AnyExtension.kt6
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt9
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackerMode.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt19
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt4
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt51
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt7
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt10
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt19
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt23
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt3
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt51
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt14
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt28
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersFragment.kt7
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt9
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt96
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt1
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt1
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt7
-rw-r--r--app/src/main/res/values/strings.xml2
-rw-r--r--fakelocation/fakelocationdemo/build.gradle2
-rw-r--r--fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt29
-rw-r--r--fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt12
-rw-r--r--fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt6
-rw-r--r--permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java6
-rw-r--r--permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java11
-rw-r--r--permissionse/src/main/AndroidManifest.xml2
-rw-r--r--permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt67
-rw-r--r--permissionsstandalone/build.gradle2
-rw-r--r--permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt12
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt3
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt36
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt16
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt8
-rw-r--r--privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt2
-rw-r--r--trackers/build.gradle102
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt305
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt31
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt33
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt33
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt39
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt2
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt3
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt33
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt49
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt33
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt33
-rw-r--r--trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt48
60 files changed, 741 insertions, 685 deletions
diff --git a/app/build.gradle b/app/build.gradle
index d4d6a51..82717d3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -115,6 +115,10 @@ android {
dataBinding true
viewBinding true
}
+
+ lintOptions {
+ disable 'MissingTranslation'
+ }
}
dependencies {
@@ -130,6 +134,8 @@ dependencies {
implementation 'foundation.e:privacymodule.tor:1.3.0-orbot-16.6.2'
+ implementation 'foundation.e:elib:0.0.1-alpha11'
+
implementation (
Libs.Kotlin.stdlib,
Libs.AndroidX.coreKtx,
@@ -150,9 +156,6 @@ dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
- implementation 'foundation.e:elib:0.0.1-alpha11'
}
static def log(Object val) {
diff --git a/app/src/androidTest/java/foundation/e/privacycentralapp/ExampleInstrumentedTest.kt b/app/src/androidTest/java/foundation/e/privacycentralapp/ExampleInstrumentedTest.kt
deleted file mode 100644
index f42f093..0000000
--- a/app/src/androidTest/java/foundation/e/privacycentralapp/ExampleInstrumentedTest.kt
+++ /dev/null
@@ -1,39 +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
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.Assert
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-@RunWith(AndroidJUnit4::class)
-class ExampleInstrumentedTest {
- @Test
- fun useAppContext() {
- // Context of the app under test.
- val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- Assert.assertEquals("foundation.e.privacycentralapp", appContext.packageName)
- }
-}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index 2e24d4c..670b81e 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -106,15 +106,17 @@ class DependencyContainer(val app: Application) {
)
}
- val viewModelsFactory by lazy { ViewModelsFactory(
- getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase,
- trackersStatisticsUseCase = trackersStatisticsUseCase,
- trackersStateUseCase = trackersStateUseCase,
- fakeLocationStateUseCase = fakeLocationStateUseCase,
- ipScramblerModule = ipScramblerModule,
- ipScramblingStateUseCase = ipScramblingStateUseCase,
- appListUseCase = appListUseCase
- ) }
+ val viewModelsFactory by lazy {
+ ViewModelsFactory(
+ getQuickPrivacyStateUseCase = getQuickPrivacyStateUseCase,
+ trackersStatisticsUseCase = trackersStatisticsUseCase,
+ trackersStateUseCase = trackersStateUseCase,
+ fakeLocationStateUseCase = fakeLocationStateUseCase,
+ ipScramblerModule = ipScramblerModule,
+ ipScramblingStateUseCase = ipScramblingStateUseCase,
+ appListUseCase = appListUseCase
+ )
+ }
// Background
fun initBackgroundSingletons() {
@@ -140,15 +142,15 @@ class ViewModelsFactory(
private val ipScramblerModule: IIpScramblerModule,
private val ipScramblingStateUseCase: IpScramblingStateUseCase,
private val appListUseCase: AppListUseCase
-): ViewModelProvider.Factory {
+) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
return when (modelClass) {
AppTrackersViewModel::class.java -> {
val fallbackUid = android.os.Process.myPid()
- val appUid = extras[DEFAULT_ARGS_KEY]?.
- getInt(AppTrackersFragment.PARAM_APP_UID, fallbackUid)?: fallbackUid
+ val appUid = extras[DEFAULT_ARGS_KEY]
+ ?.getInt(AppTrackersFragment.PARAM_APP_UID, fallbackUid) ?: fallbackUid
AppTrackersViewModel(
appUid = appUid,
diff --git a/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
index b23be3d..28e96e0 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
@@ -19,14 +19,12 @@ package foundation.e.privacycentralapp
import android.app.Application
import com.mapbox.mapboxsdk.Mapbox
-import kotlinx.coroutines.FlowPreview
class PrivacyCentralApplication : Application() {
// Initialize the dependency container.
val dependencyContainer: DependencyContainer by lazy { DependencyContainer(this) }
-
override fun onCreate() {
super.onCreate()
Mapbox.getTelemetry()?.setUserTelemetryRequestState(false)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt b/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt
index c83d8f9..13511da 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/UpdateTrackersWorker.kt
@@ -45,8 +45,9 @@ class UpdateTrackersWorker(appContext: Context, workerParams: WorkerParameters)
fun periodicUpdate(context: Context) {
val request = PeriodicWorkRequestBuilder<UpdateTrackersWorker>(
- 7, TimeUnit.DAYS)
- .setConstraints(constraints).build()
+ 7, TimeUnit.DAYS
+ )
+ .setConstraints(constraints).build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
UpdateTrackersWorker::class.qualifiedName ?: "",
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/TextViewHelpers.kt b/app/src/main/java/foundation/e/privacycentralapp/common/TextViewHelpers.kt
index 25a3633..d85f4a7 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/common/TextViewHelpers.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/TextViewHelpers.kt
@@ -60,4 +60,4 @@ private fun asteriskAsInfoIconSpannable(
}
}
return spannable
-} \ No newline at end of file
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/extensions/AnyExtension.kt b/app/src/main/java/foundation/e/privacycentralapp/common/extensions/AnyExtension.kt
index 5c73df9..71de99a 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/common/extensions/AnyExtension.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/extensions/AnyExtension.kt
@@ -19,10 +19,4 @@ package foundation.e.privacycentralapp.common.extensions
import android.content.Context
-fun Any.toText(context: Context) = when (this) {
- is Int -> context.getString(this)
- is String -> this
- else -> this.toString()
-}
-
fun Int.dpToPxF(context: Context): Float = this.toFloat() * context.resources.displayMetrics.density
diff --git a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt
index 672f260..d39ee43 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/data/repositories/LocalStateRepository.kt
@@ -20,6 +20,7 @@ package foundation.e.privacycentralapp.data.repositories
import android.content.Context
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
+import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
@@ -51,12 +52,12 @@ class LocalStateRepository(context: Context) {
return isFirstActivation
}
- private val _otherVpnRunning = MutableSharedFlow<Boolean>()
- suspend fun emitOtherVpnRunning() {
- _otherVpnRunning.emit(true)
+ private val _otherVpnRunning = MutableSharedFlow<ApplicationDescription>()
+ suspend fun emitOtherVpnRunning(appDesc: ApplicationDescription) {
+ _otherVpnRunning.emit(appDesc)
}
- val otherVpnRunning: SharedFlow<Boolean> = _otherVpnRunning
+ val otherVpnRunning: SharedFlow<ApplicationDescription> = _otherVpnRunning
var quickPrivacyEnabledFlow: StateFlow<Boolean> = quickPrivacyEnabledMutableFlow
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackerMode.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackerMode.kt
index ae70ba3..9f057be 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackerMode.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackerMode.kt
@@ -19,4 +19,4 @@ package foundation.e.privacycentralapp.domain.entities
enum class TrackerMode {
DENIED, CUSTOM, VULNERABLE
-} \ No newline at end of file
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
index 1426891..e9da855 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/FakeLocationStateUseCase.kt
@@ -67,8 +67,8 @@ class FakeLocationStateUseCase(
get() = appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
private fun hasAcquireLocationPermission(): Boolean {
- return (appContext.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
- || permissionsModule.toggleDangerousPermission(appDesc, android.Manifest.permission.ACCESS_FINE_LOCATION, true)
+ return (appContext.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) ||
+ permissionsModule.toggleDangerousPermission(appDesc, android.Manifest.permission.ACCESS_FINE_LOCATION, true)
}
private fun applySettings(isQuickPrivacyEnabled: Boolean, fakeLocation: Pair<Float, Float>?, isSpecificLocation: Boolean = false) {
@@ -85,8 +85,8 @@ class FakeLocationStateUseCase(
}
private fun hasAcquireMockLocationPermission(): Boolean {
- return (permissionsModule.getAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION) == AppOpModes.ALLOWED)
- || permissionsModule.setAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpModes.ALLOWED)
+ return (permissionsModule.getAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION) == AppOpModes.ALLOWED) ||
+ permissionsModule.setAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION, AppOpModes.ALLOWED)
}
fun setSpecificLocation(latitude: Float, longitude: Float) {
@@ -140,7 +140,8 @@ class FakeLocationStateUseCase(
override fun onLocationChanged(location: Location) {
currentLocation.update { previous ->
if ((previous?.time ?: 0) + 1800 < location.time ||
- (previous?.accuracy ?: Float.MAX_VALUE) > location.accuracy) {
+ (previous?.accuracy ?: Float.MAX_VALUE) > location.accuracy
+ ) {
location
} else {
previous
@@ -193,10 +194,10 @@ class FakeLocationStateUseCase(
)
- locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)?:
- locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)?.let {
- localListener.onLocationChanged(it)
- }
+ locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
+ ?: locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)?.let {
+ localListener.onLocationChanged(it)
+ }
} catch (se: SecurityException) {
Log.e(TAG, "Missing permission", se)
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt
index e1f773f..46e054e 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/GetQuickPrivacyStateUseCase.kt
@@ -22,6 +22,7 @@ import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
import foundation.e.privacycentralapp.domain.entities.LocationMode
import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.domain.entities.TrackerMode
+import foundation.e.privacymodules.permissions.data.ApplicationDescription
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
@@ -106,6 +107,5 @@ class GetQuickPrivacyStateUseCase(
localStateRepository.setShowQuickPrivacyDisabledMessage(false)
}
- val otherVpnRunning: SharedFlow<Boolean> = localStateRepository.otherVpnRunning
-
+ val otherVpnRunning: SharedFlow<ApplicationDescription> = localStateRepository.otherVpnRunning
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt
index 3320721..cb9fcd5 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/IpScramblingStateUseCase.kt
@@ -20,6 +20,10 @@ package foundation.e.privacycentralapp.domain.usecases
import foundation.e.privacycentralapp.data.repositories.AppListsRepository
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode.HIDE_IP
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode.HIDE_IP_LOADING
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode.REAL_IP
+import foundation.e.privacycentralapp.domain.entities.InternetPrivacyMode.REAL_IP_LOADING
import foundation.e.privacymodules.ipscramblermodule.IIpScramblerModule
import foundation.e.privacymodules.permissions.IPermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
@@ -126,30 +130,33 @@ class IpScramblingStateUseCase(
}
private fun applySettings(isQuickPrivacyEnabled: Boolean, isIpScramblingEnabled: Boolean) {
+ val settingEnabled = isQuickPrivacyEnabled && isIpScramblingEnabled
+ val currentMode = localStateRepository.internetPrivacyMode.value
+
when {
- isQuickPrivacyEnabled && isIpScramblingEnabled -> when (localStateRepository.internetPrivacyMode.value) {
- InternetPrivacyMode.REAL_IP, InternetPrivacyMode.REAL_IP_LOADING -> {
- var intent = ipScramblerModule.prepareAndroidVpn()
- if (intent != null) {
- permissionsPrivacyModule.setVpnPackageAuthorization(appDesc.packageName)
- intent = ipScramblerModule.prepareAndroidVpn()
- }
-
- if (intent != null) {
- coroutineScope.launch {
- localStateRepository.emitOtherVpnRunning()
- }
- localStateRepository.setIpScramblingSetting(enabled = false)
- } else {
- ipScramblerModule.start(enableNotification = false)
- }
- }
- else -> {}
- }
- else -> when (localStateRepository.internetPrivacyMode.value) {
- InternetPrivacyMode.HIDE_IP, InternetPrivacyMode.HIDE_IP_LOADING -> ipScramblerModule.stop()
- else -> {}
+ settingEnabled && currentMode in setOf(REAL_IP, REAL_IP_LOADING) ->
+ applyStartIpScrambling()
+
+ !settingEnabled && currentMode in setOf(HIDE_IP, HIDE_IP_LOADING) ->
+ ipScramblerModule.stop()
+
+ else -> {}
+ }
+ }
+
+ private fun applyStartIpScrambling() {
+ ipScramblerModule.prepareAndroidVpn()?.let {
+ permissionsPrivacyModule.setVpnPackageAuthorization(appDesc.packageName)
+ permissionsPrivacyModule.getAlwaysOnVpnPackage()
+ }?.let {
+ coroutineScope.launch {
+ localStateRepository.emitOtherVpnRunning(
+ permissionsPrivacyModule.getApplicationDescription(packageName = it, withIcon = false)
+ )
}
+ localStateRepository.setIpScramblingSetting(enabled = false)
+ } ?: run {
+ ipScramblerModule.start(enableNotification = false)
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt
index 10c1ad0..17e5096 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStateUseCase.kt
@@ -20,7 +20,6 @@ package foundation.e.privacycentralapp.domain.usecases
import foundation.e.privacycentralapp.data.repositories.AppListsRepository
import foundation.e.privacycentralapp.data.repositories.LocalStateRepository
import foundation.e.privacycentralapp.data.repositories.TrackersRepository
-import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
import foundation.e.privacymodules.trackers.api.IBlockTrackersPrivacyModule
import foundation.e.privacymodules.trackers.api.ITrackTrackersPrivacyModule
@@ -63,8 +62,9 @@ class TrackersStateUseCase(
return appListsRepository.getApplicationDescription(appUid)
}
- fun isWhitelisted(appUid: Int)
- = isWhitelisted(appUid, appListsRepository, blockTrackersPrivacyModule)
+ fun isWhitelisted(appUid: Int): Boolean {
+ return isWhitelisted(appUid, appListsRepository, blockTrackersPrivacyModule)
+ }
fun getTrackersWhitelistIds(appUid: Int): List<String> {
return if (appUid == appListsRepository.dummySystemApp.uid) {
@@ -108,7 +108,6 @@ class TrackersStateUseCase(
}
}
-
fun isWhitelisted(
appUid: Int,
appListsRepository: AppListsRepository,
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
index 0a47bc5..57ab1a4 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt
@@ -166,17 +166,15 @@ class TrackersStatisticsUseCase(
acc.addAll(blockTrackersPrivacyModule.getWhiteList(app.uid).map { it.id })
acc
}
-
} else {
trackers = trackTrackersPrivacyModule.getTrackersForApp(appUid)
whiteListedTrackersIds = blockTrackersPrivacyModule.getWhiteList(appUid)
.map { it.id }.toSet()
}
- return trackers.sortedBy { it.label.lowercase() }.map { tracker -> tracker to whiteListedTrackersIds.any { tracker.id == it }}
+ return trackers.sortedBy { it.label.lowercase() }.map { tracker -> tracker to whiteListedTrackersIds.any { tracker.id == it } }
}
-
fun getCalls(appUid: Int): Pair<Int, Int> {
return if (appUid == appListsRepository.dummySystemApp.uid) {
appListsRepository.getHiddenSystemApps().map {
@@ -211,10 +209,12 @@ class TrackersStatisticsUseCase(
blockTrackersPrivacyModule.getWhiteList(app.uid).size
},
blockedLeaks = appListsRepository.foldForHiddenSystemApp(app.uid) {
- appUid -> callsByApp.getOrDefault(appUid, 0 to 0).first
+ appUid ->
+ callsByApp.getOrDefault(appUid, 0 to 0).first
},
leaks = appListsRepository.foldForHiddenSystemApp(app.uid) {
- appUid -> callsByApp.getOrDefault(appUid, 0 to 0).second
+ appUid ->
+ callsByApp.getOrDefault(appUid, 0 to 0).second
}
)
}.sortedWith(mostLeakedAppsComparator)
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 4d38ec8..6cd259e 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
@@ -163,8 +163,11 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
}
}
is SingleEvent.ToastMessageSingleEvent ->
- Toast.makeText(requireContext(), event.message, Toast.LENGTH_LONG)
- .show()
+ Toast.makeText(
+ requireContext(),
+ getString(event.message, *event.args.toTypedArray()),
+ Toast.LENGTH_LONG
+ ).show()
}
}
}
@@ -200,11 +203,13 @@ class DashboardFragment : NavToolbarFragment(R.layout.fragment_dashboard) {
binding.togglePrivacyCentral.isChecked = state.quickPrivacyState.isEnabled()
- binding.stateTrackers.text = getString(when(state.trackerMode) {
- TrackerMode.DENIED -> R.string.dashboard_state_trackers_on
- TrackerMode.VULNERABLE -> R.string.dashboard_state_trackers_off
- TrackerMode.CUSTOM -> R.string.dashboard_state_trackers_custom
- })
+ binding.stateTrackers.text = getString(
+ when (state.trackerMode) {
+ TrackerMode.DENIED -> R.string.dashboard_state_trackers_on
+ TrackerMode.VULNERABLE -> R.string.dashboard_state_trackers_off
+ TrackerMode.CUSTOM -> R.string.dashboard_state_trackers_custom
+ }
+ )
binding.stateTrackers.setTextColor(
getColor(
requireContext(),
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt
index fb00f07..04b7ae8 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardState.kt
@@ -33,4 +33,4 @@ data class DashboardState(
val dayStatistics: List<Pair<Int, Int>>? = null,
val dayLabels: List<String>? = null,
val showQuickPrivacyDisabledMessage: Boolean = false
-) \ No newline at end of file
+)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
index cd7e414..d7d74c6 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
@@ -17,6 +17,7 @@
package foundation.e.privacycentralapp.features.dashboard
+import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import foundation.e.privacycentralapp.R
@@ -76,9 +77,12 @@ class DashboardViewModel(
_state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
},
getPrivacyStateUseCase.otherVpnRunning.map {
- _singleEvents.emit(SingleEvent.ToastMessageSingleEvent(
- R.string.ipscrambling_error_always_on_vpn_already_running
- ))
+ _singleEvents.emit(
+ SingleEvent.ToastMessageSingleEvent(
+ R.string.ipscrambling_error_always_on_vpn_already_running,
+ listOf(it.label ?: "")
+ )
+ )
}
).collect {}
}
@@ -120,9 +124,11 @@ class DashboardViewModel(
val isFirstActivation = getPrivacyStateUseCase.toggleReturnIsFirstActivation()
fetchStatistics().first()
- if (isFirstActivation) _singleEvents.emit(SingleEvent.ToastMessageSingleEvent(
- message = R.string.dashboard_first_ipscrambling_activation
- ))
+ if (isFirstActivation) _singleEvents.emit(
+ SingleEvent.ToastMessageSingleEvent(
+ message = R.string.dashboard_first_ipscrambling_activation
+ )
+ )
}
private suspend fun actionShowMostLeakedApp() = withContext(Dispatchers.IO) {
@@ -139,7 +145,10 @@ class DashboardViewModel(
object NavigateToLocationSingleEvent : SingleEvent()
object NavigateToPermissionsSingleEvent : SingleEvent()
data class NavigateToAppDetailsEvent(val appDesc: ApplicationDescription) : SingleEvent()
- data class ToastMessageSingleEvent(val message: Int) : SingleEvent()
+ data class ToastMessageSingleEvent(
+ @StringRes val message: Int,
+ val args: List<Any> = emptyList()
+ ) : SingleEvent()
}
sealed class Action {
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
index 749fae4..99aa217 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
@@ -33,7 +33,6 @@ import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
import foundation.e.privacycentralapp.common.ToggleAppsAdapter
-import foundation.e.privacycentralapp.common.extensions.toText
import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.common.setToolTipForAsterisk
import foundation.e.privacycentralapp.databinding.FragmentInternetActivityPolicyBinding
@@ -137,7 +136,7 @@ class InternetPrivacyFragment : NavToolbarFragment(R.layout.fragment_internet_ac
viewModel.singleEvents.collect { event ->
when (event) {
is InternetPrivacyViewModel.SingleEvent.ErrorEvent -> {
- displayToast(event.error.toText(requireContext()))
+ displayToast(getString(event.errorResId, *event.args.toTypedArray()))
}
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt
index 25e911f..6991196 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyState.kt
@@ -34,4 +34,4 @@ data class InternetPrivacyState(
}
val selectedLocationPosition get() = availableLocationIds.indexOf(selectedLocation)
-} \ No newline at end of file
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt
index ab5e24d..be6cd4d 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt
@@ -17,6 +17,7 @@
package foundation.e.privacycentralapp.features.internetprivacy
+import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import foundation.e.privacycentralapp.R
@@ -54,20 +55,20 @@ class InternetPrivacyViewModel(
private val _singleEvents = MutableSharedFlow<SingleEvent>()
val singleEvents = _singleEvents.asSharedFlow()
-
-
val availablesLocationsIds = listOf("", *ipScramblerModule.getAvailablesLocations().sorted().toTypedArray())
init {
viewModelScope.launch(Dispatchers.IO) {
- _state.update { it.copy(
- mode = ipScramblingStateUseCase.internetPrivacyMode.value,
- availableLocationIds = availablesLocationsIds,
- selectedLocation = ipScramblerModule.exitCountry) }
+ _state.update {
+ it.copy(
+ mode = ipScramblingStateUseCase.internetPrivacyMode.value,
+ availableLocationIds = availablesLocationsIds,
+ selectedLocation = ipScramblerModule.exitCountry
+ )
+ }
}
}
-
@OptIn(FlowPreview::class)
suspend fun doOnStartedState() = withContext(Dispatchers.IO) {
launch {
@@ -76,23 +77,26 @@ class InternetPrivacyViewModel(
_state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
},
appListUseCase.getAppsUsingInternet().map { apps ->
- _state.update { s -> s.copy(
- availableApps = apps,
- bypassTorApps = ipScramblingStateUseCase.bypassTorApps
- ) }
+ _state.update { s ->
+ s.copy(
+ availableApps = apps,
+ bypassTorApps = ipScramblingStateUseCase.bypassTorApps
+ )
+ }
},
if (getQuickPrivacyStateUseCase.isQuickPrivacyEnabled)
ipScramblingStateUseCase.internetPrivacyMode.map {
_state.update { s -> s.copy(mode = it) }
}
else ipScramblingStateUseCase.configuredMode.map {
- _state.update { s -> s.copy(
- mode = if (it) InternetPrivacyMode.HIDE_IP
- else InternetPrivacyMode.REAL_IP
- ) }
+ _state.update { s ->
+ s.copy(
+ mode = if (it) InternetPrivacyMode.HIDE_IP
+ else InternetPrivacyMode.REAL_IP
+ )
+ }
}
).collect {}
-
}
launch {
@@ -108,9 +112,13 @@ class InternetPrivacyViewModel(
launch {
getQuickPrivacyStateUseCase.otherVpnRunning.collect {
- _singleEvents.emit(SingleEvent.ErrorEvent(R.string.ipscrambling_error_always_on_vpn_already_running))
- _state.update { it.copy(forceRedraw = !it.forceRedraw)}
-
+ _singleEvents.emit(
+ SingleEvent.ErrorEvent(
+ R.string.ipscrambling_error_always_on_vpn_already_running,
+ listOf(it.label ?: "")
+ )
+ )
+ _state.update { it.copy(forceRedraw = !it.forceRedraw) }
}
}
}
@@ -148,7 +156,10 @@ class InternetPrivacyViewModel(
}
sealed class SingleEvent {
- data class ErrorEvent(val error: Any) : SingleEvent()
+ data class ErrorEvent(
+ @StringRes val errorResId: Int,
+ val args: List<Any> = emptyList()
+ ) : SingleEvent()
}
sealed class Action {
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 2e014e2..537d0b6 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
@@ -86,8 +86,8 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
private val locationPermissionRequest = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
- if (permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false)
- || permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false)
+ if (permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) ||
+ permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false)
) {
viewModel.submitAction(Action.StartListeningLocation)
} // TODO: else.
@@ -167,10 +167,12 @@ class FakeLocationFragment : NavToolbarFragment(R.layout.fragment_fake_location)
}
is FakeLocationViewModel.SingleEvent.RequestLocationPermission -> {
// TODO for standalone: rationale dialog
- locationPermissionRequest.launch(arrayOf(
- Manifest.permission.ACCESS_FINE_LOCATION,
- Manifest.permission.ACCESS_COARSE_LOCATION
- ))
+ locationPermissionRequest.launch(
+ arrayOf(
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.ACCESS_COARSE_LOCATION
+ )
+ )
}
is FakeLocationViewModel.SingleEvent.LocationUpdatedEvent -> {
// Nothing here, another collect linked to mapbox view.
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt
index c7bcd98..9513f77 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationState.kt
@@ -27,4 +27,4 @@ data class FakeLocationState(
val specificLongitude: Float? = null,
val forceRefresh: Boolean = false,
val showQuickPrivacyDisabledMessage: Boolean = false
-) \ No newline at end of file
+)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
index afba3d0..8db3537 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt
@@ -58,28 +58,32 @@ class FakeLocationViewModel(
launch {
merge(
fakeLocationStateUseCase.configuredLocationMode.map { (mode, lat, lon) ->
- _state.update { s -> s.copy(
- mode = mode,
- specificLatitude = lat,
- specificLongitude = lon
- ) }
+ _state.update { s ->
+ s.copy(
+ mode = mode,
+ specificLatitude = lat,
+ specificLongitude = lon
+ )
+ }
},
getQuickPrivacyStateUseCase.showQuickPrivacyDisabledMessage.map {
_state.update { s -> s.copy(showQuickPrivacyDisabledMessage = it) }
},
specificLocationInputFlow
.debounce(SET_SPECIFIC_LOCATION_DELAY).map { action ->
- fakeLocationStateUseCase.setSpecificLocation(action.latitude, action.longitude)
- }
+ fakeLocationStateUseCase.setSpecificLocation(action.latitude, action.longitude)
+ }
).collect {}
}
launch {
fakeLocationStateUseCase.currentLocation.collect { location ->
- _singleEvents.emit(SingleEvent.LocationUpdatedEvent(
- mode = _state.value.mode,
- location = location
- ))
+ _singleEvents.emit(
+ SingleEvent.LocationUpdatedEvent(
+ mode = _state.value.mode,
+ location = location
+ )
+ )
}
}
}
@@ -110,7 +114,7 @@ class FakeLocationViewModel(
sealed class SingleEvent {
data class LocationUpdatedEvent(val mode: LocationMode, val location: Location?) : SingleEvent()
- object RequestLocationPermission: SingleEvent()
+ object RequestLocationPermission : SingleEvent()
data class ErrorEvent(val error: String) : SingleEvent()
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt
index f51ff18..2437366 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersState.kt
@@ -26,4 +26,4 @@ data class TrackersState(
val yearStatistics: TrackersPeriodicStatistics? = null,
val apps: List<AppWithCounts>? = null,
val showQuickPrivacyDisabledMessage: Boolean = false
-) \ No newline at end of file
+)
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
index f49152e..3869c39 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
@@ -52,11 +52,13 @@ class TrackersViewModel(
trackersStatisticsUseCase.listenUpdates().map {
trackersStatisticsUseCase.getDayMonthYearStatistics()
.let { (day, month, year) ->
- _state.update { s -> s.copy(
+ _state.update { s ->
+ s.copy(
dayStatistics = day,
monthStatistics = month,
yearStatistics = year
- ) }
+ )
+ }
}
},
trackersStatisticsUseCase.getAppsWithCounts().map {
@@ -74,7 +76,7 @@ class TrackersViewModel(
}
}
- suspend private fun actionClickApp(action: Action.ClickAppAction) {
+ private suspend fun actionClickApp(action: Action.ClickAppAction) {
state.value.apps?.find { it.packageName == action.packageName }?.let {
_singleEvents.emit(SingleEvent.OpenAppDetailsEvent(it))
}
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 ae169b4..cd4f6b2 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
@@ -36,7 +36,6 @@ import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.common.NavToolbarFragment
import foundation.e.privacycentralapp.common.initQuickPrivacySnackbar
import foundation.e.privacycentralapp.databinding.ApptrackersFragmentBinding
-import foundation.e.privacycentralapp.common.extensions.toText
import kotlinx.coroutines.launch
class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
@@ -69,7 +68,8 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (arguments == null ||
- requireArguments().getInt(PARAM_APP_UID, Int.MIN_VALUE) == Int.MIN_VALUE) {
+ requireArguments().getInt(PARAM_APP_UID, Int.MIN_VALUE) == Int.MIN_VALUE
+ ) {
activity?.supportFragmentManager?.popBackStack()
}
}
@@ -110,7 +110,7 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
viewModel.singleEvents.collect { event ->
when (event) {
is AppTrackersViewModel.SingleEvent.ErrorEvent ->
- displayToast(event.error.toText(requireContext()))
+ displayToast(getString(event.errorResId))
is AppTrackersViewModel.SingleEvent.OpenUrl ->
try {
startActivity(Intent(Intent.ACTION_VIEW, event.url))
@@ -151,7 +151,6 @@ class AppTrackersFragment : NavToolbarFragment(R.layout.apptrackers_fragment) {
binding.blockAllToggle.isChecked = state.isBlockingActivated
-
val trackersStatus = state.getTrackersStatus()
if (!trackersStatus.isNullOrEmpty()) {
binding.trackersListTitle.isVisible = state.isBlockingActivated
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt
index ffa1f36..d6d0858 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersState.kt
@@ -29,11 +29,12 @@ data class AppTrackersState(
val isQuickPrivacyEnabled: Boolean = false,
val showQuickPrivacyDisabledMessage: Boolean = false,
) {
- fun getTrackersStatus(): List<Pair<Tracker, Boolean>>?
- = trackersWithWhiteList?.map { it.first to !it.second }
+ fun getTrackersStatus(): List<Pair<Tracker, Boolean>>? {
+ return trackersWithWhiteList?.map { it.first to !it.second }
+ }
fun getTrackersCount() = trackersWithWhiteList?.size ?: 0
fun getBlockedTrackersCount(): Int = if (isQuickPrivacyEnabled && isBlockingActivated)
- trackersWithWhiteList?.count { !it.second }?: 0
+ trackersWithWhiteList?.count { !it.second } ?: 0
else 0
-} \ No newline at end of file
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt
index faa4e6b..52ef2c4 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/apptrackers/AppTrackersViewModel.kt
@@ -18,6 +18,7 @@
package foundation.e.privacycentralapp.features.trackers.apptrackers
import android.net.Uri
+import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import foundation.e.privacycentralapp.domain.usecases.GetQuickPrivacyStateUseCase
@@ -53,11 +54,13 @@ class AppTrackersViewModel(
init {
viewModelScope.launch(Dispatchers.IO) {
- _state.update { it.copy(
- appDesc = trackersStateUseCase.getApplicationDescription(appUid),
- isBlockingActivated = !trackersStateUseCase.isWhitelisted(appUid),
- trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid),
- ) }
+ _state.update {
+ it.copy(
+ appDesc = trackersStateUseCase.getApplicationDescription(appUid),
+ isBlockingActivated = !trackersStateUseCase.isWhitelisted(appUid),
+ trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid),
+ )
+ }
}
}
@@ -74,56 +77,69 @@ class AppTrackersViewModel(
}
fun submitAction(action: Action) = viewModelScope.launch {
- when (action) {
- is Action.BlockAllToggleAction -> blockAllToggleAction(action)
- is Action.ToggleTrackerAction -> toggleTrackerAction(action)
- is Action.ClickTracker ->actionClickTracker(action)
- is Action.CloseQuickPrivacyDisabledMessage ->
- getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
- }
+ when (action) {
+ is Action.BlockAllToggleAction -> blockAllToggleAction(action)
+ is Action.ToggleTrackerAction -> toggleTrackerAction(action)
+ is Action.ClickTracker -> actionClickTracker(action)
+ is Action.CloseQuickPrivacyDisabledMessage ->
+ getQuickPrivacyStateUseCase.resetQuickPrivacyDisabledMessage()
+ }
}
- private suspend fun blockAllToggleAction(action: Action.BlockAllToggleAction)
- = withContext(Dispatchers.IO) {
- trackersStateUseCase.toggleAppWhitelist(appUid, !action.isBlocked)
- _state.update { it.copy(
- isBlockingActivated = !trackersStateUseCase.isWhitelisted(appUid)
- ) }
+ private suspend fun blockAllToggleAction(action: Action.BlockAllToggleAction) {
+ withContext(Dispatchers.IO) {
+ trackersStateUseCase.toggleAppWhitelist(appUid, !action.isBlocked)
+ _state.update {
+ it.copy(
+ isBlockingActivated = !trackersStateUseCase.isWhitelisted(appUid)
+ )
+ }
+ }
}
- private suspend fun toggleTrackerAction(action: Action.ToggleTrackerAction)
- = withContext(Dispatchers.IO) {
- if (state.value.isBlockingActivated) {
- trackersStateUseCase.blockTracker(appUid, action.tracker, action.isBlocked)
- _state.update { it.copy(
- trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid)
- ) }
+ private suspend fun toggleTrackerAction(action: Action.ToggleTrackerAction) {
+ withContext(Dispatchers.IO) {
+ if (state.value.isBlockingActivated) {
+ trackersStateUseCase.blockTracker(appUid, action.tracker, action.isBlocked)
+ _state.update {
+ it.copy(
+ trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(
+ appUid
+ )
+ )
+ }
+ }
}
}
- private suspend fun actionClickTracker(action: Action.ClickTracker)
- = withContext(Dispatchers.IO) {
- action.tracker.exodusId?.let {
- try {
- _singleEvents.emit(SingleEvent.OpenUrl(
- Uri.parse(exodusBaseUrl + it)
- ))
- } catch (e: Exception) {}
+ private suspend fun actionClickTracker(action: Action.ClickTracker) {
+ withContext(Dispatchers.IO) {
+ action.tracker.exodusId?.let {
+ try {
+ _singleEvents.emit(
+ SingleEvent.OpenUrl(
+ Uri.parse(exodusBaseUrl + it)
+ )
+ )
+ } catch (e: Exception) {
+ }
+ }
}
}
private fun fetchStatistics() {
val (blocked, leaked) = trackersStatisticsUseCase.getCalls(appUid)
- return _state.update { s -> s.copy(
- trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid),
- leaked = leaked,
- blocked = blocked,
- ) }
+ return _state.update { s ->
+ s.copy(
+ trackersWithWhiteList = trackersStatisticsUseCase.getTrackersWithWhiteList(appUid),
+ leaked = leaked,
+ blocked = blocked,
+ )
+ }
}
-
sealed class SingleEvent {
- data class ErrorEvent(val error: Any) : SingleEvent()
+ data class ErrorEvent(@StringRes val errorResId: Int) : SingleEvent()
data class OpenUrl(val url: Uri) : SingleEvent()
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt b/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
index 63ec27f..58ac797 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
@@ -28,7 +28,6 @@ import foundation.e.privacycentralapp.PrivacyCentralApplication
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.features.dashboard.DashboardFragment
import foundation.e.privacycentralapp.features.trackers.TrackersFragment
-import kotlinx.coroutines.FlowPreview
open class MainActivity : FragmentActivity(R.layout.activity_main) {
override fun onPostCreate(savedInstanceState: Bundle?) {
diff --git a/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt b/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt
index e886cd8..ddfcc2e 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/widget/Widget.kt
@@ -141,7 +141,6 @@ class Widget : AppWidgetProvider() {
}
}
-
override fun onAppWidgetOptionsChanged(
context: Context,
appWidgetManager: AppWidgetManager,
diff --git a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
index 27589a8..682e5cc 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
@@ -29,8 +29,8 @@ import android.widget.RemoteViews
import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.Widget
import foundation.e.privacycentralapp.Widget.Companion.isDarkText
-import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.common.extensions.dpToPxF
+import foundation.e.privacycentralapp.domain.entities.QuickPrivacyState
import foundation.e.privacycentralapp.domain.entities.TrackerMode
import foundation.e.privacycentralapp.main.MainActivity
import foundation.e.privacycentralapp.widget.WidgetCommandReceiver.Companion.ACTION_TOGGLE_PRIVACY
@@ -44,7 +44,6 @@ data class State(
val activeTrackersCount: Int = 0,
)
-
fun render(
context: Context,
state: State,
@@ -93,7 +92,7 @@ fun render(
setTextViewText(
R.id.state_trackers,
context.getString(
- when(state.trackerMode) {
+ when (state.trackerMode) {
TrackerMode.DENIED -> R.string.widget_state_trackers_on
TrackerMode.VULNERABLE -> R.string.widget_state_trackers_off
TrackerMode.CUSTOM -> R.string.widget_state_trackers_custom
@@ -277,7 +276,7 @@ fun applyDarkText(context: Context, state: State, views: RemoteViews) {
R.id.graph_legend_blocked,
R.id.graph_legend_allowed,
- )
+ )
.forEach {
setTextColor(
it,
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d3157d5..8705ac5 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -54,7 +54,7 @@
<string name="ipscrambling_select_app">Apply this setting to all selected applications * :</string>
<string name="ipscrambling_app_list_infos">Only apps with Internet permission are listed.</string>
<string name="ipscrambling_error_quickprivacy_disabled">Enabled Quick Privacy to use functionalities</string>
- <string name="ipscrambling_error_always_on_vpn_already_running">Please disable any 3rd-party VPN in order for Advanced Privacy to hide your real IP address.</string>
+ <string name="ipscrambling_error_always_on_vpn_already_running">Please disable the 3rd-party VPN %s in order for Advanced Privacy to hide your real IP address.</string>
<string name="ipscrambling_warning_starting_long">Our scrambling IP service is taking time to launch. It can take a few minutes. Leaving the screen won\'t interrupt the process.</string>
<!-- Location -->
<string name="location_title">Manage my location</string>
diff --git a/fakelocation/fakelocationdemo/build.gradle b/fakelocation/fakelocationdemo/build.gradle
index c182b2f..7e05b8a 100644
--- a/fakelocation/fakelocationdemo/build.gradle
+++ b/fakelocation/fakelocationdemo/build.gradle
@@ -68,4 +68,4 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
-} \ No newline at end of file
+}
diff --git a/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt b/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt
index 1b0a35b..42cf658 100644
--- a/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt
+++ b/fakelocation/fakelocationdemo/src/main/java/foundation/e/privacymodules/fakelocationdemo/MainActivity.kt
@@ -58,7 +58,6 @@ class MainActivity : AppCompatActivity() {
)
}
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
@@ -79,7 +78,7 @@ class MainActivity : AppCompatActivity() {
binding.mockedLocation = mockedLocation
}
- private val listener = object: LocationListener {
+ private val listener = object : LocationListener {
override fun onLocationChanged(location: Location) {
binding.currentLocation = "lat: ${location.latitude} - lon: ${location.longitude}"
}
@@ -130,16 +129,19 @@ class MainActivity : AppCompatActivity() {
private val locationPermissionRequest = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
- if (permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false)
- || permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false)
+ if (permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) ||
+ permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false)
) {
startLocationUpdates()
}
}
private fun requireLocationPermissions() {
- if (ContextCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ if (ContextCompat.checkSelfPermission(
+ this,
+ Manifest.permission.ACCESS_COARSE_LOCATION
+ ) == PackageManager.PERMISSION_GRANTED
+ ) {
startLocationUpdates()
} else {
// Before you perform the actual permission request, check whether your app
@@ -152,19 +154,20 @@ class MainActivity : AppCompatActivity() {
)
)
}
-
}
@Suppress("UNUSED_PARAMETER")
fun onClickPermission(view: View?) {
- val isGranted = permissionsModule.setAppOpMode(appDesc, AppOpsManager.OPSTR_MOCK_LOCATION,
- AppOpModes.ALLOWED)
+ val isGranted = permissionsModule.setAppOpMode(
+ appDesc, AppOpsManager.OPSTR_MOCK_LOCATION,
+ AppOpModes.ALLOWED
+ )
if (isGranted) {
updateData("")
return
}
- //dev mode disabled
+ // dev mode disabled
val alertDialog = AlertDialog.Builder(this)
alertDialog
.setTitle("Mock location disabled")
@@ -177,7 +180,7 @@ class MainActivity : AppCompatActivity() {
fun onClickReset(view: View?) {
try {
fakeLocationModule.stopFakeLocation()
- } catch(e: Exception) {
+ } catch (e: Exception) {
Log.e(TAG, "Can't stop FakeLocation", e)
}
}
@@ -185,11 +188,11 @@ class MainActivity : AppCompatActivity() {
private fun setFakeLocation(latitude: Double, longitude: Double) {
try {
fakeLocationModule.startFakeLocation()
- } catch(e: Exception) {
+ } catch (e: Exception) {
Log.e(TAG, "Can't startFakeLocation", e)
}
fakeLocationModule.setFakeLocation(latitude, longitude)
- updateData("lat: ${latitude} - lon: ${longitude}")
+ updateData("lat: $latitude - lon: $longitude")
}
@Suppress("UNUSED_PARAMETER")
diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt
index 709963d..4245836 100644
--- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt
+++ b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationModule.kt
@@ -34,7 +34,7 @@ import android.util.Log
*
* @param context an Android context, to retrieve system services for example.
*/
-class FakeLocationModule(private val context: Context): IFakeLocationModule {
+class FakeLocationModule(private val context: Context) : IFakeLocationModule {
companion object {
private const val TAG = "FakeLocationModule"
}
@@ -60,11 +60,10 @@ class FakeLocationModule(private val context: Context): IFakeLocationModule {
providers.forEach { provider ->
try {
locationManager.removeTestProvider(provider)
- } catch(e: Exception) {
+ } catch (e: Exception) {
Log.w(TAG, "Test provider $provider already removed.")
}
-
locationManager.addTestProvider(
provider,
false,
@@ -75,12 +74,13 @@ class FakeLocationModule(private val context: Context): IFakeLocationModule {
true,
true,
ProviderProperties.POWER_USAGE_LOW,
- ProviderProperties.ACCURACY_FINE)
+ ProviderProperties.ACCURACY_FINE
+ )
try {
locationManager.setTestProviderEnabled(provider, true)
} catch (e: Exception) {
- Log.e(TAG, "Can't enable test $provider", e)
- }
+ Log.e(TAG, "Can't enable test $provider", e)
+ }
}
}
diff --git a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt
index 1337ddd..34620fe 100644
--- a/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt
+++ b/fakelocation/src/main/java/foundation/e/privacymodules/fakelocation/FakeLocationService.kt
@@ -17,7 +17,6 @@
package foundation.e.privacymodules.fakelocation
-
import android.app.Service
import android.content.Context
import android.content.Intent
@@ -25,7 +24,7 @@ import android.os.CountDownTimer
import android.os.IBinder
import android.util.Log
-class FakeLocationService: Service() {
+class FakeLocationService : Service() {
enum class Actions {
START_FAKE_LOCATION
@@ -83,10 +82,9 @@ class FakeLocationService: Service() {
super.onDestroy()
}
-
private fun initTimer() {
countDownTimer?.cancel()
- countDownTimer = object: CountDownTimer(PERIOD_UPDATES_SERIE, PERIOD_LOCATION_UPDATE) {
+ countDownTimer = object : CountDownTimer(PERIOD_UPDATES_SERIE, PERIOD_LOCATION_UPDATE) {
override fun onTick(millisUntilFinished: Long) {
fakeLocation?.let {
try {
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java b/permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java
index d7f6ccf..53440e0 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java
+++ b/permissionse/libs/hidden-apis-stub/src/main/java/android/net/IConnectivityManager.java
@@ -32,7 +32,7 @@ public interface IConnectivityManager {
@TargetApi(29)
@DeprecatedSinceApi(
api = 31,
- message = "TODO"
+ message = "Moved to android.net.VpnManager"
)
boolean prepareVpn(String oldPackage, String newPackage, int userId) throws RemoteException;
@@ -53,9 +53,9 @@ public interface IConnectivityManager {
@TargetApi(29)
@DeprecatedSinceApi(
api = 31,
- message = "TODO"
+ message = "Moved to android.net.VpnManager"
)
- String getAlwaysOnVpnPackage(int userId) throws RemoteException;
+ public String getAlwaysOnVpnPackage(int userId) throws RemoteException;
public abstract static class Stub extends Binder implements IConnectivityManager {
public static IConnectivityManager asInterface(IBinder obj) {
diff --git a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java b/permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java
index 7cc9b6a..bdb9e95 100644
--- a/permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java
+++ b/permissionse/libs/hidden-apis-stub/src/main/java/android/net/VpnManager.java
@@ -21,6 +21,7 @@ import android.annotation.TargetApi;
import androidx.annotation.DeprecatedSinceApi;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresPermission;
// Stub based on:
// https://gitlab.e.foundation/e/os/android_frameworks_base/-/blob/[SDK_VERSION]/core/java/android/net/VpnManager.java
@@ -50,4 +51,14 @@ public class VpnManager {
int userId,
int vpnType
) {}
+
+ @TargetApi(31)
+ @DeprecatedSinceApi(
+ api = 33,
+ message = "Check disponibility in SDK33"
+ )
+ @RequiresPermission("android.permission.CONTROL_ALWAYS_ON_VPN")
+ public String getAlwaysOnVpnPackageForUser(int userId) {
+ return null;
+ }
}
diff --git a/permissionse/src/main/AndroidManifest.xml b/permissionse/src/main/AndroidManifest.xml
index 6a7e416..428a612 100644
--- a/permissionse/src/main/AndroidManifest.xml
+++ b/permissionse/src/main/AndroidManifest.xml
@@ -33,4 +33,6 @@
/>
<uses-permission android:name="android.permission.CONTROL_VPN"
tools:ignore="ProtectedPermissions" />
+ <uses-permission android:name="android.permission.CONTROL_ALWAYS_ON_VPN"
+ tools:ignore="ProtectedPermissions" />
</manifest>
diff --git a/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt b/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
index fe5b7ac..83711dd 100644
--- a/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
+++ b/permissionse/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2022 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.privacymodules.permissions
import android.annotation.TargetApi
@@ -18,10 +35,10 @@ import foundation.e.privacymodules.permissions.data.ApplicationDescription
/**
* Implements [IPermissionsPrivacyModule] with all privileges of a system app.
*/
-class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(context) {
+class PermissionsPrivacyModule(context: Context) : APermissionsPrivacyModule(context) {
- private val appOpsManager: AppOpsManager get()
- = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
+ private val appOpsManager: AppOpsManager
+ get() = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
/**
* @see IPermissionsPrivacyModule.toggleDangerousPermission
@@ -67,7 +84,7 @@ class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(cont
}
override fun setVpnPackageAuthorization(packageName: String): Boolean {
- return when(Build.VERSION.SDK_INT) {
+ return when (Build.VERSION.SDK_INT) {
29 -> setVpnPackageAuthorizationSDK29(packageName)
30 -> setVpnPackageAuthorizationSDK30(packageName)
31, 32 -> setVpnPackageAuthorizationSDK32(packageName)
@@ -81,7 +98,8 @@ class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(cont
@TargetApi(29)
private fun setVpnPackageAuthorizationSDK29(packageName: String): Boolean {
val service: IConnectivityManager = IConnectivityManager.Stub.asInterface(
- ServiceManager.getService(Context.CONNECTIVITY_SERVICE))
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE)
+ )
try {
if (service.prepareVpn(null, packageName, UserHandle.myUserId())) {
@@ -101,7 +119,8 @@ class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(cont
@TargetApi(30)
private fun setVpnPackageAuthorizationSDK30(packageName: String): Boolean {
val service: IConnectivityManager = IConnectivityManager.Stub.asInterface(
- ServiceManager.getService(Context.CONNECTIVITY_SERVICE))
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE)
+ )
try {
if (service.prepareVpn(null, packageName, UserHandle.myUserId())) {
@@ -136,4 +155,40 @@ class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(cont
}
return false
}
+
+ override fun getAlwaysOnVpnPackage(): String? {
+ return when (Build.VERSION.SDK_INT) {
+ 29, 30 -> getAlwaysOnVpnPackageSDK29()
+ 31, 32 -> getAlwaysOnVpnPackageSDK32()
+ else -> {
+ Log.e("Permissions-e", "Bad android sdk version")
+ null
+ }
+ }
+ }
+
+ @TargetApi(29)
+ private fun getAlwaysOnVpnPackageSDK29(): String? {
+ val service: IConnectivityManager = IConnectivityManager.Stub.asInterface(
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE)
+ )
+
+ return try {
+ service.getAlwaysOnVpnPackage(UserHandle.myUserId())
+ } catch (e: java.lang.Exception) {
+ Log.e("Permissions-e", "Bad android sdk version ", e)
+ return null
+ }
+ }
+
+ @TargetApi(31)
+ private fun getAlwaysOnVpnPackageSDK32(): String? {
+ val vpnManager = context.getSystemService(Context.VPN_MANAGEMENT_SERVICE) as VpnManager
+ return try {
+ vpnManager.getAlwaysOnVpnPackageForUser(UserHandle.myUserId())
+ } catch (e: java.lang.Exception) {
+ Log.e("Permissions-e", "Bad android sdk version ", e)
+ return null
+ }
+ }
}
diff --git a/permissionsstandalone/build.gradle b/permissionsstandalone/build.gradle
index ef03f2b..8d2def8 100644
--- a/permissionsstandalone/build.gradle
+++ b/permissionsstandalone/build.gradle
@@ -57,4 +57,4 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
-} \ No newline at end of file
+}
diff --git a/permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt b/permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
index d32cada..98ebdc3 100644
--- a/permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
+++ b/permissionsstandalone/src/main/java/foundation/e/privacymodules/permissions/PermissionsPrivacyModule.kt
@@ -18,15 +18,13 @@
package foundation.e.privacymodules.permissions
import android.content.Context
-import android.os.Build
-import android.provider.Settings
import foundation.e.privacymodules.permissions.data.AppOpModes
import foundation.e.privacymodules.permissions.data.ApplicationDescription
/**
* Implements [IPermissionsPrivacyModule] using only API authorized on the PlayStore.
*/
-class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(context) {
+class PermissionsPrivacyModule(context: Context) : APermissionsPrivacyModule(context) {
/**
* @see IPermissionsPrivacyModule.toggleDangerousPermission
* Return an ManualAction to go toggle manually the permission in the ap page of the settings.
@@ -34,8 +32,8 @@ class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(cont
override fun toggleDangerousPermission(
appDesc: ApplicationDescription,
permissionName: String,
- grant: Boolean): Boolean = false
-
+ grant: Boolean
+ ): Boolean = false
override fun setAppOpMode(
appDesc: ApplicationDescription,
@@ -46,4 +44,8 @@ class PermissionsPrivacyModule(context: Context): APermissionsPrivacyModule(cont
override fun setVpnPackageAuthorization(packageName: String): Boolean {
return false
}
+
+ override fun getAlwaysOnVpnPackage(): String? {
+ return null
+ }
}
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt
index bcf82d2..9bf8aba 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt
+++ b/privacymodule-api/src/main/java/foundation/e/privacymodules/DependencyInjector.kt
@@ -26,7 +26,6 @@ object DependencyInjector {
this.dnsBlocker = dnsBlocker
}
-
lateinit var dnsBlocker: IDNSBlocker
private set
-} \ No newline at end of file
+}
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt
index 68f7ee1..9d7e675 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt
+++ b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/APermissionsPrivacyModule.kt
@@ -14,6 +14,7 @@
* 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.privacymodules.permissions
import android.app.AppOpsManager
@@ -34,7 +35,7 @@ import foundation.e.privacymodules.permissions.data.PermissionDescription
* versions of the module.
* @param context an Android context, to retrieve packageManager for example.
*/
-abstract class APermissionsPrivacyModule(protected val context: Context): IPermissionsPrivacyModule {
+abstract class APermissionsPrivacyModule(protected val context: Context) : IPermissionsPrivacyModule {
companion object {
private const val TAG = "PermissionsModule"
@@ -59,9 +60,11 @@ abstract class APermissionsPrivacyModule(protected val context: Context): IPermi
/**
* @see IPermissionsPrivacyModule.getInstalledApplications
*/
- override fun getApplicationDescription(packageName: String): ApplicationDescription {
+ override fun getApplicationDescription(packageName: String, withIcon: Boolean): ApplicationDescription {
val appDesc = buildApplicationDescription(context.packageManager.getApplicationInfo(packageName, 0), false)
- appDesc.icon = getApplicationIcon(appDesc.packageName)
+ if (withIcon) {
+ appDesc.icon = getApplicationIcon(appDesc.packageName)
+ }
return appDesc
}
@@ -102,13 +105,16 @@ abstract class APermissionsPrivacyModule(protected val context: Context): IPermi
val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
val mode = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- appOps.checkOpNoThrow(appOpPermissionName,
+ appOps.checkOpNoThrow(
+ appOpPermissionName,
- appDesc.uid, appDesc.packageName)
+ appDesc.uid, appDesc.packageName
+ )
} else {
appOps.unsafeCheckOpNoThrow(
appOpPermissionName,
- appDesc.uid, appDesc.packageName)
+ appDesc.uid, appDesc.packageName
+ )
}
return AppOpModes.getByModeValue(mode)
@@ -138,15 +144,15 @@ abstract class APermissionsPrivacyModule(protected val context: Context): IPermi
}
}
- override fun buildApplicationDescription(appInfo: ApplicationInfo, withIcon: Boolean)
- : ApplicationDescription {
- return ApplicationDescription(
- packageName = appInfo.packageName,
- uid = appInfo.uid,
- label = getAppLabel(appInfo),
- icon = if (withIcon) getApplicationIcon(appInfo.packageName) else null
- )
- }
+ override fun buildApplicationDescription(appInfo: ApplicationInfo, withIcon: Boolean):
+ ApplicationDescription {
+ return ApplicationDescription(
+ packageName = appInfo.packageName,
+ uid = appInfo.uid,
+ label = getAppLabel(appInfo),
+ icon = if (withIcon) getApplicationIcon(appInfo.packageName) else null
+ )
+ }
private fun getAppLabel(appInfo: ApplicationInfo): CharSequence {
return context.packageManager.getApplicationLabel(appInfo)
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt
index ba85f13..6624798 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt
+++ b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/IPermissionsPrivacyModule.kt
@@ -28,7 +28,10 @@ import foundation.e.privacymodules.permissions.data.PermissionDescription
*/
interface IPermissionsPrivacyModule {
- fun buildApplicationDescription(appInfo: ApplicationInfo, withIcon: Boolean = true): ApplicationDescription
+ fun buildApplicationDescription(
+ appInfo: ApplicationInfo,
+ withIcon: Boolean = true
+ ): ApplicationDescription
/**
* List the installed application on the device which have not the FLAGS_SYSTEM.
@@ -51,13 +54,12 @@ interface IPermissionsPrivacyModule {
fun getPermissionDescription(permissionName: String): PermissionDescription
-
/**
* Get the filled up [ApplicationDescription] for the app specified by its [packageName]
* @param packageName the appId of the app
* @return the informations about the app.
*/
- fun getApplicationDescription(packageName: String): ApplicationDescription
+ fun getApplicationDescription(packageName: String, withIcon: Boolean = true): ApplicationDescription
/**
* Check if the current runtime permission is granted for the specified app.
@@ -68,7 +70,6 @@ interface IPermissionsPrivacyModule {
*/
fun isDangerousPermissionGranted(packageName: String, permissionName: String): Boolean
-
/**
* Get the appOps mode for the specified [appOpPermissionName] of the specified application.
*
@@ -94,7 +95,6 @@ interface IPermissionsPrivacyModule {
grant: Boolean
): Boolean
-
/**
* Change the appOp Mode for the specified appOpPermission and application.
* @param appDesc the application
@@ -124,4 +124,8 @@ interface IPermissionsPrivacyModule {
*/
fun setVpnPackageAuthorization(packageName: String): Boolean
-} \ No newline at end of file
+ /**
+ * Returns the package name of the currently set always-on VPN application, or null.
+ */
+ fun getAlwaysOnVpnPackage(): String?
+}
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt
index 367645d..4764596 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt
+++ b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/AppOpModes.kt
@@ -17,7 +17,11 @@
package foundation.e.privacymodules.permissions.data
-import android.app.AppOpsManager.*
+import android.app.AppOpsManager.MODE_ALLOWED
+import android.app.AppOpsManager.MODE_DEFAULT
+import android.app.AppOpsManager.MODE_ERRORED
+import android.app.AppOpsManager.MODE_FOREGROUND
+import android.app.AppOpsManager.MODE_IGNORED
import android.os.Build
enum class AppOpModes(val modeValue: Int) {
@@ -34,7 +38,7 @@ enum class AppOpModes(val modeValue: Int) {
IGNORED.modeValue to IGNORED,
ERRORED.modeValue to ERRORED,
DEFAULT.modeValue to DEFAULT,
- )
+ )
fun getByModeValue(modeValue: Int): AppOpModes {
return byMode.get(modeValue) ?: DEFAULT
diff --git a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt
index 9ed297d..127192b 100644
--- a/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt
+++ b/privacymodule-api/src/main/java/foundation/e/privacymodules/permissions/data/PermissionDescription.kt
@@ -23,4 +23,4 @@ data class PermissionDescription(
val group: String?,
var label: CharSequence?,
var description: CharSequence?
-) \ No newline at end of file
+)
diff --git a/trackers/build.gradle b/trackers/build.gradle
index 409996a..f888acf 100644
--- a/trackers/build.gradle
+++ b/trackers/build.gradle
@@ -1,51 +1,51 @@
-/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- */
-
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-
-android {
- compileSdkVersion buildConfig.compileSdk
-
- defaultConfig {
- minSdkVersion buildConfig.minSdk
- targetSdkVersion buildConfig.targetSdk
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
- }
- }
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-}
-
-dependencies {
- implementation project(':privacymodule-api')
- implementation(
- Libs.Kotlin.stdlib,
- Libs.AndroidX.coreKtx,
- Libs.Coroutines.core
- )
-}
+/*
+ Copyright (C) 2022 ECORP
+
+ 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 2
+ 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ */
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ compileSdkVersion buildConfig.compileSdk
+
+ defaultConfig {
+ minSdkVersion buildConfig.minSdk
+ targetSdkVersion buildConfig.targetSdk
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation project(':privacymodule-api')
+ implementation(
+ Libs.Kotlin.stdlib,
+ Libs.AndroidX.coreKtx,
+ Libs.Coroutines.core
+ )
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt
index 01ae5b7..737aa4a 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerRunnable.kt
@@ -1,164 +1,141 @@
-/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- */
-/*
- PersonalDNSFilter 1.5
- Copyright (C) 2017 Ingo Zenz
- Copyright (C) 2021 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
- */
-package foundation.e.privacymodules.trackers
-
-import android.content.Context
-import android.content.pm.PackageManager
-import android.net.LocalServerSocket
-import android.system.ErrnoException
-import android.system.Os
-import android.system.OsConstants
-import android.util.Log
-import foundation.e.privacymodules.trackers.data.TrackersRepository
-import foundation.e.privacymodules.trackers.data.WhitelistRepository
-import java.io.BufferedReader
-import java.io.IOException
-import java.io.InputStreamReader
-import java.io.PrintWriter
-
-class DNSBlockerRunnable(
- ct: Context,
- private val trackersLogger: TrackersLogger,
- private val trackersRepository: TrackersRepository,
- private val whitelistRepository: WhitelistRepository
-) : Runnable {
- var resolverReceiver: LocalServerSocket? = null
- var stopped = false
- private var eBrowserAppUid = -1
-
- companion object {
- private const val SOCKET_NAME = "foundation.e.advancedprivacy"
- private const val E_BROWSER_DOT_SERVER = "chrome.cloudflare-dns.com"
- private const val TAG = "DNSBlockerRunnable"
- }
-
- init {
- initEBrowserDoTFix(ct)
- }
-
- @Synchronized
- fun stop() {
- stopped = true
- closeSocket()
- }
-
- private fun closeSocket() {
- // Known bug and workaround that LocalServerSocket::close is not working well
- // https://issuetracker.google.com/issues/36945762
- if (resolverReceiver != null) {
- try {
- Os.shutdown(resolverReceiver!!.fileDescriptor, OsConstants.SHUT_RDWR)
- resolverReceiver!!.close()
- resolverReceiver = null
- } catch (e: ErrnoException) {
- if (e.errno != OsConstants.EBADF) {
- Log.w(TAG, "Socket already closed")
- } else {
- Log.e(TAG, "Exception: cannot close DNS port on stop $SOCKET_NAME !", e)
- }
- } catch (e: Exception) {
- Log.e(TAG, "Exception: cannot close DNS port on stop $SOCKET_NAME !", e)
- }
- }
- }
-
- override fun run() {
- val resolverReceiver = try {
- LocalServerSocket(SOCKET_NAME)
- } catch (eio: IOException) {
- Log.e(TAG, "Exception:Cannot open DNS port $SOCKET_NAME !", eio)
- return
- }
-
- this.resolverReceiver = resolverReceiver
- Log.d(TAG, "DNSFilterProxy running on port $SOCKET_NAME !")
-
- while (!stopped) {
- try {
- val socket = resolverReceiver.accept()
- val reader = BufferedReader(InputStreamReader(socket.inputStream))
- val line = reader.readLine()
- val params = line.split(",").toTypedArray()
- val output = socket.outputStream
- val writer = PrintWriter(output, true)
- val domainName = params[0]
- val appUid = params[1].toInt()
- var isBlocked = false
- if (isEBrowserDoTBlockFix(appUid, domainName)) {
- isBlocked = true
- } else if (trackersRepository.isTracker(domainName)) {
- val trackerId = trackersRepository.getTrackerId(domainName)
- if (shouldBlock(appUid, trackerId)) {
- writer.println("block")
- isBlocked = true
- }
- trackersLogger.logAccess(trackerId, appUid, isBlocked)
- }
- if (!isBlocked) {
- writer.println("pass")
- }
- socket.close()
- // Printing bufferedreader data
- } catch (e: IOException) {
- Log.w(TAG, "Exception while listening DNS resolver", e)
- }
- }
- }
-
- private fun initEBrowserDoTFix(context: Context) {
- try {
- eBrowserAppUid =
- context.packageManager.getApplicationInfo("foundation.e.browser", 0).uid
- } catch (e: PackageManager.NameNotFoundException) {
- Log.i(TAG, "no E Browser package found.")
- }
- }
-
- private fun isEBrowserDoTBlockFix(appUid: Int, hostname: String): Boolean {
- return appUid == eBrowserAppUid && E_BROWSER_DOT_SERVER == hostname
- }
-
- private fun shouldBlock(appUid: Int, trackerId: String?): Boolean {
- return whitelistRepository.isBlockingEnabled &&
- !whitelistRepository.isAppWhiteListed(appUid) &&
- !whitelistRepository.isTrackerWhiteListedForApp(trackerId, appUid)
- }
-
-
-} \ No newline at end of file
+/*
+ * Copyright (C) 2022 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.privacymodules.trackers
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.net.LocalServerSocket
+import android.system.ErrnoException
+import android.system.Os
+import android.system.OsConstants
+import android.util.Log
+import foundation.e.privacymodules.trackers.data.TrackersRepository
+import foundation.e.privacymodules.trackers.data.WhitelistRepository
+import java.io.BufferedReader
+import java.io.IOException
+import java.io.InputStreamReader
+import java.io.PrintWriter
+
+class DNSBlockerRunnable(
+ context: Context,
+ private val trackersLogger: TrackersLogger,
+ private val trackersRepository: TrackersRepository,
+ private val whitelistRepository: WhitelistRepository
+) : Runnable {
+ var resolverReceiver: LocalServerSocket? = null
+ var stopped = false
+ private var eBrowserAppUid = -1
+
+ companion object {
+ private const val SOCKET_NAME = "foundation.e.advancedprivacy"
+ private const val E_BROWSER_DOT_SERVER = "chrome.cloudflare-dns.com"
+ private const val TAG = "DNSBlockerRunnable"
+ }
+
+ init {
+ initEBrowserDoTFix(context)
+ }
+
+ @Synchronized
+ fun stop() {
+ stopped = true
+ closeSocket()
+ }
+
+ private fun closeSocket() {
+ // Known bug and workaround that LocalServerSocket::close is not working well
+ // https://issuetracker.google.com/issues/36945762
+ if (resolverReceiver != null) {
+ try {
+ Os.shutdown(resolverReceiver!!.fileDescriptor, OsConstants.SHUT_RDWR)
+ resolverReceiver!!.close()
+ resolverReceiver = null
+ } catch (e: ErrnoException) {
+ if (e.errno != OsConstants.EBADF) {
+ Log.w(TAG, "Socket already closed")
+ } else {
+ Log.e(TAG, "Exception: cannot close DNS port on stop $SOCKET_NAME !", e)
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Exception: cannot close DNS port on stop $SOCKET_NAME !", e)
+ }
+ }
+ }
+
+ override fun run() {
+ val resolverReceiver = try {
+ LocalServerSocket(SOCKET_NAME)
+ } catch (eio: IOException) {
+ Log.e(TAG, "Exception:Cannot open DNS port $SOCKET_NAME !", eio)
+ return
+ }
+
+ this.resolverReceiver = resolverReceiver
+ Log.d(TAG, "DNSFilterProxy running on port $SOCKET_NAME !")
+
+ while (!stopped) {
+ try {
+ val socket = resolverReceiver.accept()
+ val reader = BufferedReader(InputStreamReader(socket.inputStream))
+ val line = reader.readLine()
+ val params = line.split(",").toTypedArray()
+ val output = socket.outputStream
+ val writer = PrintWriter(output, true)
+ val domainName = params[0]
+ val appUid = params[1].toInt()
+ var isBlocked = false
+ if (isEBrowserDoTBlockFix(appUid, domainName)) {
+ isBlocked = true
+ } else if (trackersRepository.isTracker(domainName)) {
+ val trackerId = trackersRepository.getTrackerId(domainName)
+ if (shouldBlock(appUid, trackerId)) {
+ writer.println("block")
+ isBlocked = true
+ }
+ trackersLogger.logAccess(trackerId, appUid, isBlocked)
+ }
+ if (!isBlocked) {
+ writer.println("pass")
+ }
+ socket.close()
+ // Printing bufferedreader data
+ } catch (e: IOException) {
+ Log.w(TAG, "Exception while listening DNS resolver", e)
+ }
+ }
+ }
+
+ private fun initEBrowserDoTFix(context: Context) {
+ try {
+ eBrowserAppUid =
+ context.packageManager.getApplicationInfo("foundation.e.browser", 0).uid
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.i(TAG, "no E Browser package found.")
+ }
+ }
+
+ private fun isEBrowserDoTBlockFix(appUid: Int, hostname: String): Boolean {
+ return appUid == eBrowserAppUid && E_BROWSER_DOT_SERVER == hostname
+ }
+
+ private fun shouldBlock(appUid: Int, trackerId: String?): Boolean {
+ return whitelistRepository.isBlockingEnabled &&
+ !whitelistRepository.isAppWhiteListed(appUid) &&
+ !whitelistRepository.isTrackerWhiteListedForApp(trackerId, appUid)
+ }
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt
index 3162422..97a0fda 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/DNSBlockerService.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2021 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * 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.privacymodules.trackers
import android.app.Service
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt
index 30bba7b..69b4f28 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/ForegroundStarter.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2021 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * 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.privacymodules.trackers
import android.app.Notification
@@ -43,4 +42,4 @@ object ForegroundStarter {
service.startForeground(1337, notification)
}
}
-} \ No newline at end of file
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt
index 6d2abec..99e2148 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/TrackersLogger.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * Copyright (C) 2022 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.privacymodules.trackers
import android.content.Context
@@ -66,4 +65,4 @@ class TrackersLogger(context: Context) {
}
inner class DetectedTracker(var trackerId: String?, var appUid: Int, var wasBlocked: Boolean)
-} \ No newline at end of file
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt
index 46729fd..25f0f2a 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/BlockTrackersPrivacyModule.kt
@@ -1,26 +1,25 @@
/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * Copyright (C) 2022 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.privacymodules.trackers.api
-import foundation.e.privacymodules.trackers.data.WhitelistRepository
import android.content.Context
import foundation.e.privacymodules.trackers.data.TrackersRepository
+import foundation.e.privacymodules.trackers.data.WhitelistRepository
class BlockTrackersPrivacyModule(context: Context) : IBlockTrackersPrivacyModule {
private val mListeners = mutableListOf<IBlockTrackersPrivacyModule.Listener>()
@@ -31,7 +30,7 @@ class BlockTrackersPrivacyModule(context: Context) : IBlockTrackersPrivacyModule
private var instance: BlockTrackersPrivacyModule? = null
fun getInstance(context: Context): BlockTrackersPrivacyModule {
- return instance?: BlockTrackersPrivacyModule(context).apply { instance = this }
+ return instance ?: BlockTrackersPrivacyModule(context).apply { instance = this }
}
}
@@ -86,6 +85,4 @@ class BlockTrackersPrivacyModule(context: Context) : IBlockTrackersPrivacyModule
override fun setWhiteListed(appUid: Int, isWhiteListed: Boolean) {
whitelistRepository.setWhiteListed(appUid, isWhiteListed)
}
-
-
-} \ No newline at end of file
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt
index b07e210..9e1a041 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/IBlockTrackersPrivacyModule.kt
@@ -22,7 +22,6 @@ package foundation.e.privacymodules.trackers.api
*/
interface IBlockTrackersPrivacyModule {
-
/**
* Get the state of the blockin module
* @return true when blocking is enabled, false otherwise.
@@ -69,7 +68,6 @@ interface IBlockTrackersPrivacyModule {
*/
fun isWhitelisted(appUid: Int): Boolean
-
/**
* List the white listed trackers for an App specified by it uid
*/
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt
index 5f1fa92..264f247 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/ITrackTrackersPrivacyModule.kt
@@ -61,7 +61,6 @@ interface ITrackTrackersPrivacyModule {
*/
fun getPastYearTrackersCount(): Int
-
/**
* Return number of trackers calls by hours, for the last 24hours.
* @return list of 24 numbers of trackers calls by hours
@@ -100,4 +99,4 @@ interface ITrackTrackersPrivacyModule {
fun removeListener(listener: Listener)
fun clearListeners()
-} \ No newline at end of file
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt
index d8f75aa..18c56c9 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/api/TrackTrackersPrivacyModule.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2021 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * 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.privacymodules.trackers.api
import android.content.Context
@@ -33,7 +32,7 @@ class TrackTrackersPrivacyModule(private val context: Context) : ITrackTrackersP
private var instance: TrackTrackersPrivacyModule? = null
fun getInstance(context: Context): TrackTrackersPrivacyModule {
- return instance?: TrackTrackersPrivacyModule(context).apply { instance = this }
+ return instance ?: TrackTrackersPrivacyModule(context).apply { instance = this }
}
}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt
index c93fe90..21edb56 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsDatabase.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * Copyright (C) 2022 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.privacymodules.trackers.data
import android.content.ContentValues
@@ -97,10 +96,12 @@ class StatsDatabase(context: Context) :
val selection = "$COLUMN_NAME_TIMESTAMP >= ?"
val selectionArg = arrayOf("" + minTimestamp)
- val projection = ("$COLUMN_NAME_TIMESTAMP, " +
- "STRFTIME('${sqlitePeriodFormat}', DATETIME($COLUMN_NAME_TIMESTAMP, 'unixepoch', 'localtime')) $PROJECTION_NAME_PERIOD," +
- "SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM, " +
- "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM")
+ val projection = (
+ "$COLUMN_NAME_TIMESTAMP, " +
+ "STRFTIME('$sqlitePeriodFormat', DATETIME($COLUMN_NAME_TIMESTAMP, 'unixepoch', 'localtime')) $PROJECTION_NAME_PERIOD," +
+ "SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM, " +
+ "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
+ )
val cursor = db.rawQuery(
"SELECT $projection FROM $TABLE_NAME WHERE $selection" +
@@ -208,7 +209,7 @@ class StatsDatabase(context: Context) :
val db = readableDatabase
val projection = "$COLUMN_NAME_APP_UID, $COLUMN_NAME_TRACKER"
val cursor = db.rawQuery(
- "SELECT DISTINCT $projection FROM $TABLE_NAME", //+
+ "SELECT DISTINCT $projection FROM $TABLE_NAME", // +
arrayOf()
)
val countByApp = mutableMapOf<Int, Int>()
@@ -260,7 +261,7 @@ class StatsDatabase(context: Context) :
val selectionArg = arrayOf("" + appUid, "" + minTimestamp)
val projection =
"SUM($COLUMN_NAME_NUMBER_CONTACTED) $PROJECTION_NAME_CONTACTED_SUM," +
- "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
+ "SUM($COLUMN_NAME_NUMBER_BLOCKED) $PROJECTION_NAME_BLOCKED_SUM"
val cursor = db.rawQuery(
"SELECT $projection FROM $TABLE_NAME WHERE $selection",
selectionArg
@@ -363,7 +364,6 @@ class StatsDatabase(context: Context) :
return entry
}
-
fun getTrackers(appUids: List<Int>?): List<Tracker> {
synchronized(lock) {
val columns = arrayOf(COLUMN_NAME_TRACKER, COLUMN_NAME_APP_UID)
@@ -444,5 +444,4 @@ class StatsDatabase(context: Context) :
val columnIndex = getColumnIndex(columnName)
return if (columnIndex >= 0) getString(columnIndex) else ""
}
-
-} \ No newline at end of file
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt
index f5d217a..16d8ec6 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/StatsRepository.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * Copyright (C) 2022 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.privacymodules.trackers.data
import android.content.Context
@@ -80,4 +79,4 @@ class StatsRepository private constructor(context: Context) {
fun getMostLeakedApp(periodCount: Int, periodUnit: TemporalUnit): Int {
return database.getMostLeakedApp(periodCount, periodUnit)
}
-} \ No newline at end of file
+}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt
index bc4d50b..994bccf 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/TrackersRepository.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * Copyright (C) 2022 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.privacymodules.trackers.data
import foundation.e.privacymodules.trackers.api.Tracker
@@ -27,7 +26,7 @@ class TrackersRepository private constructor() {
companion object {
private var instance: TrackersRepository? = null
fun getInstance(): TrackersRepository {
- return instance?: TrackersRepository().apply { instance = this }
+ return instance ?: TrackersRepository().apply { instance = this }
}
}
diff --git a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt
index 65a8c39..e9f049d 100644
--- a/trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt
+++ b/trackers/src/main/java/foundation/e/privacymodules/trackers/data/WhitelistRepository.kt
@@ -1,21 +1,20 @@
/*
- Copyright (C) 2022 ECORP
-
- 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 2
- 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, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+ * Copyright (C) 2022 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.privacymodules.trackers.data
import android.content.Context
@@ -34,7 +33,7 @@ class WhitelistRepository private constructor(context: Context) {
private const val KEY_APP_TRACKERS_WHITELIST_PREFIX = "app_trackers_whitelist_"
private var instance: WhitelistRepository? = null
fun getInstance(context: Context): WhitelistRepository {
- return instance?: WhitelistRepository(context).apply { instance = this }
+ return instance ?: WhitelistRepository(context).apply { instance = this }
}
}
@@ -51,13 +50,13 @@ class WhitelistRepository private constructor(context: Context) {
private fun reloadAppsWhiteList() {
appsWhitelist = prefs.getStringSet(KEY_APPS_WHITELIST, HashSet())?.mapNotNull {
- try { it.toInt() } catch(e: Exception) { null }
- }?.toHashSet()?: HashSet()
+ try { it.toInt() } catch (e: Exception) { null }
+ }?.toHashSet() ?: HashSet()
}
private fun reloadAppTrackersWhiteList(appUid: Int) {
val key = buildAppTrackersKey(appUid)
- trackersWhitelistByApp[appUid] = prefs.getStringSet(key, HashSet())?: HashSet()
+ trackersWhitelistByApp[appUid] = prefs.getStringSet(key, HashSet()) ?: HashSet()
}
private fun reloadAllAppTrackersWhiteList() {
@@ -70,8 +69,6 @@ class WhitelistRepository private constructor(context: Context) {
}
}
-
-
var isBlockingEnabled: Boolean = false
get() = field
set(enabled) {
@@ -79,9 +76,8 @@ class WhitelistRepository private constructor(context: Context) {
field = enabled
}
-
fun setWhiteListed(appUid: Int, isWhiteListed: Boolean) {
- val current = prefs.getStringSet(KEY_APPS_WHITELIST, HashSet())?.toHashSet()?: HashSet()
+ val current = prefs.getStringSet(KEY_APPS_WHITELIST, HashSet())?.toHashSet() ?: HashSet()
if (isWhiteListed) {
current.add("" + appUid)
@@ -123,6 +119,6 @@ class WhitelistRepository private constructor(context: Context) {
val whiteListedApp: List<Int> get() = appsWhitelist.toList()
fun getWhiteListForApp(appUid: Int): List<String> {
- return trackersWhitelistByApp[appUid]?.toList()?: emptyList()
+ return trackersWhitelistByApp[appUid]?.toList() ?: emptyList()
}
-} \ No newline at end of file
+}