summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle5
-rw-r--r--app/libs/lineage-sdk.jarbin0 -> 430252 bytes
-rw-r--r--app/src/main/AndroidManifest.xml1
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt3
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/ToolbarFragment.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt105
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt29
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt9
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt6
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt6
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsAdapter.kt61
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsFragment.kt101
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt56
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt142
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt76
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt42
-rw-r--r--app/src/main/res/drawable/dummy_trackers_usage.pngbin0 -> 16635 bytes
-rw-r--r--app/src/main/res/layout/activity_main.xml2
-rw-r--r--app/src/main/res/layout/fragment_dashboard.xml160
-rw-r--r--app/src/main/res/layout/fragment_fake_location.xml6
-rw-r--r--app/src/main/res/layout/fragment_internet_activity_policy.xml46
-rw-r--r--app/src/main/res/layout/fragment_permission_apps.xml56
-rw-r--r--app/src/main/res/layout/fragment_permissions.xml30
-rw-r--r--app/src/main/res/layout/fragment_quick_protection.xml91
-rw-r--r--app/src/main/res/layout/fragment_tracker_apps.xml46
-rw-r--r--app/src/main/res/layout/fragment_trackers.xml75
-rw-r--r--app/src/main/res/layout/item_app_toggle.xml (renamed from app/src/main/res/layout/item_permission_apps.xml)24
-rw-r--r--app/src/main/res/layout/item_list_tracker.xml29
-rw-r--r--app/src/main/res/layout/item_permission.xml30
-rw-r--r--app/src/main/res/layout/topbar.xml6
-rw-r--r--app/src/main/res/values/colors.xml2
-rw-r--r--app/src/main/res/values/strings.xml7
-rw-r--r--flow-mvi/src/main/java/foundation/e/flowmvi/feature/BaseFeature.kt2
-rwxr-xr-xscripts/sign_and_push.sh13
35 files changed, 1049 insertions, 228 deletions
diff --git a/app/build.gradle b/app/build.gradle
index 24ec426..8d94e2b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -80,10 +80,15 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
+
+ aaptOptions {
+ additionalParameters '-I', 'app/libs/e-ui-sdk-1.0.1-q.jar'
+ }
}
dependencies {
compileOnly files('libs/e-ui-sdk-1.0.1-q.jar')
+ implementation files('libs/lineage-sdk.jar')
implementation project(":privacymodulesapi")
// include the google specific version of the modules, just for the google flavor
diff --git a/app/libs/lineage-sdk.jar b/app/libs/lineage-sdk.jar
new file mode 100644
index 0000000..c2f04a7
--- /dev/null
+++ b/app/libs/lineage-sdk.jar
Binary files differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7145af9..4babd46 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,6 +11,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
tools:ignore="ProtectedPermissions"
/>
+ <uses-permission android:name="lineageos.permission.ACCESS_BLOCKER" />
<application
android:name=".PrivacyCentralApplication"
diff --git a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
index 364ae4a..fcc2eaa 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/DependencyContainer.kt
@@ -26,6 +26,7 @@ import foundation.e.privacymodules.location.FakeLocation
import foundation.e.privacymodules.location.IFakeLocation
import foundation.e.privacymodules.permissions.PermissionsPrivacyModule
import foundation.e.privacymodules.permissions.data.ApplicationDescription
+import lineageos.blockers.BlockerInterface
/**
* Simple container to hold application wide dependencies.
@@ -55,4 +56,6 @@ class DependencyContainer constructor(val app: Application) {
val fakeLocationViewModelFactory by lazy {
FakeLocationViewModelFactory(locationApi)
}
+
+ val blockerService = BlockerInterface.getInstance(context)
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
index 9372a66..153e0c1 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
@@ -18,9 +18,17 @@
package foundation.e.privacycentralapp
import android.app.Application
+import foundation.e.privacycentralapp.dummy.TrackersDataSource
class PrivacyCentralApplication : Application() {
// Initialize the dependency container.
val dependencyContainer: DependencyContainer by lazy { DependencyContainer(this) }
+
+ override fun onCreate() {
+ super.onCreate()
+
+ // Inject blocker service in trackers source.
+ TrackersDataSource.injectBlockerService(dependencyContainer.blockerService)
+ }
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/ToolbarFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/common/ToolbarFragment.kt
index f156e09..5c18548 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/common/ToolbarFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/ToolbarFragment.kt
@@ -40,4 +40,6 @@ abstract class ToolbarFragment(@LayoutRes contentLayoutId: Int) : Fragment(conte
open fun setupToolbar(toolbar: MaterialToolbar) {
toolbar.title = getTitle()
}
+
+ fun getToolbar(): MaterialToolbar? = view?.findViewById(R.id.toolbar)
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt
new file mode 100644
index 0000000..b6f319c
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/dummy/TrackersDataSource.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.dummy
+
+import foundation.e.privacycentralapp.R
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import lineageos.blockers.BlockerInterface
+
+data class TrackedApp(val appName: String, val isEnabled: Boolean, val iconId: Int)
+
+data class Tracker(
+ val name: String,
+ val domain: String? = null,
+ val ipAddress: String? = null,
+ val trackedApps: List<TrackedApp>
+)
+
+object TrackersDataSource {
+
+ private lateinit var blockerService: BlockerInterface
+
+ val facebook = TrackedApp("Facebook", true, R.drawable.ic_facebook)
+ val firefox = TrackedApp("Firefox", true, R.drawable.ic_facebook)
+ val google = TrackedApp("Google", true, R.drawable.ic_facebook)
+ val whatsapp = TrackedApp("Whatsapp", true, R.drawable.ic_facebook)
+ val blisslauncher = TrackedApp("BlissLauncher", true, R.drawable.ic_facebook)
+ val youtube = TrackedApp("Youtube", true, R.drawable.ic_facebook)
+
+ val crashlytics = Tracker(
+ "Google Crashlytics",
+ domain = "|0b|crashlytics|03|com",
+ trackedApps = listOf(facebook, firefox)
+ )
+
+ val facebookAds = Tracker(
+ "Facebook Analytics",
+ domain = "|08|facebook|03|com",
+ trackedApps = listOf(facebook, whatsapp)
+ )
+ val rubiconTracker = Tracker(
+ "Rubicon Projects",
+ domain = "|03|ads|0e|rubiconproject|03|com",
+ trackedApps = listOf(google, blisslauncher, youtube)
+ )
+ val googleAnalytics = Tracker(
+ "Google Analytics",
+ domain = "|10|google-analytics|03|com",
+ trackedApps = listOf(facebook, firefox)
+ )
+
+ val _trackers =
+ MutableStateFlow(listOf(crashlytics, facebookAds, rubiconTracker, googleAnalytics))
+ val trackers = _trackers.asStateFlow()
+
+ fun injectBlockerService(blockerInterface: BlockerInterface) {
+ this.blockerService = blockerInterface
+ }
+
+ fun getTracker(name: String): Tracker? {
+ try {
+ return _trackers.value.first {
+ it.name == name
+ }
+ } catch (e: NoSuchElementException) {
+ return null
+ }
+ }
+
+ fun toggleTracker(tracker: Tracker, enable: Boolean): Boolean {
+ val result = if (!enable) {
+ blockerService.blockDomain(tracker.domain)
+ } else {
+ blockerService.unblockDomain(tracker.domain)
+ }
+
+ if (result) {
+ _trackers.value = _trackers.value.map {
+ if (it.name == tracker.name) {
+ it.copy(
+ trackedApps = it.trackedApps.map { app ->
+ app.copy(isEnabled = enable)
+ }
+ )
+ } else it
+ }
+ }
+ return result
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt
index 5a20489..c26fce1 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt
@@ -25,6 +25,7 @@ import foundation.e.flowmvi.feature.BaseFeature
import foundation.e.privacycentralapp.dummy.DummyDataSource
import foundation.e.privacycentralapp.dummy.InternetPrivacyMode
import foundation.e.privacycentralapp.dummy.LocationMode
+import foundation.e.privacycentralapp.dummy.TrackersDataSource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
@@ -76,6 +77,7 @@ class DashboardFeature(
object ShowFakeMyLocationAction : Action()
object ShowInternetActivityPrivacyAction : Action()
object ShowAppsPermissions : Action()
+ object ShowTrackers : Action()
}
sealed class Effect {
@@ -92,12 +94,14 @@ class DashboardFeature(
object LoadingDashboardEffect : Effect()
data class UpdateActiveTrackersCountEffect(val count: Int) : Effect()
+ data class UpdateTotalTrackersCountEffect(val count: Int) : Effect()
data class UpdateLocationModeEffect(val mode: LocationMode) : Effect()
data class UpdateInternetActivityModeEffect(val mode: InternetPrivacyMode) : Effect()
data class UpdateAppsUsingLocationPermEffect(val apps: Int) : Effect()
object OpenFakeMyLocationEffect : Effect()
object OpenInternetActivityPrivacyEffect : Effect()
object OpenAppsPermissionsEffect : Effect()
+ object OpenTrackersEffect : Effect()
}
companion object {
@@ -127,6 +131,11 @@ class DashboardFeature(
state.copy(activeTrackersCount = effect.count)
} else state
}
+ is Effect.UpdateTotalTrackersCountEffect -> {
+ if (state is State.DashboardState) {
+ state.copy(trackersCount = effect.count)
+ } else state
+ }
is Effect.UpdateInternetActivityModeEffect -> {
if (state is State.DashboardState) {
state.copy(internetPrivacyMode = effect.mode)
@@ -144,14 +153,27 @@ class DashboardFeature(
Effect.OpenFakeMyLocationEffect -> state
Effect.OpenAppsPermissionsEffect -> state
Effect.OpenInternetActivityPrivacyEffect -> state
+ Effect.OpenTrackersEffect -> state
}
},
actor = { _: State, action: Action ->
Log.d("Feature", "action: $action")
when (action) {
Action.ObserveDashboardAction -> merge(
- DummyDataSource.activeTrackersCount.map {
- Effect.UpdateActiveTrackersCountEffect(it)
+ TrackersDataSource.trackers.map {
+ var activeTrackersCount: Int = 0
+ outer@ for (tracker in it) {
+ for (app in tracker.trackedApps) {
+ if (!app.isEnabled) {
+ continue@outer
+ }
+ }
+ activeTrackersCount++
+ }
+ Effect.UpdateActiveTrackersCountEffect(activeTrackersCount)
+ },
+ TrackersDataSource.trackers.map {
+ Effect.UpdateTotalTrackersCountEffect(it.size)
},
DummyDataSource.appsUsingLocationPerm.map {
Effect.UpdateAppsUsingLocationPermEffect(it.size)
@@ -185,6 +207,7 @@ class DashboardFeature(
Action.ShowInternetActivityPrivacyAction -> flowOf(
Effect.OpenInternetActivityPrivacyEffect
)
+ Action.ShowTrackers -> flowOf(Effect.OpenTrackersEffect)
}
},
singleEventProducer = { state, _, effect ->
@@ -197,6 +220,8 @@ class DashboardFeature(
SingleEvent.NavigateToInternetActivityPrivacySingleEvent
else if (state is State.DashboardState && effect is Effect.OpenAppsPermissionsEffect)
SingleEvent.NavigateToPermissionsSingleEvent
+ else if (state is State.DashboardState && effect is Effect.OpenTrackersEffect)
+ SingleEvent.NavigateToTrackersSingleEvent
else null
}
)
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 c57e6cc..e7ce353 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
@@ -38,6 +38,7 @@ import foundation.e.privacycentralapp.dummy.mapToString
import foundation.e.privacycentralapp.features.internetprivacy.InternetPrivacyFragment
import foundation.e.privacycentralapp.features.location.FakeLocationFragment
import foundation.e.privacycentralapp.features.permissions.PermissionsFragment
+import foundation.e.privacycentralapp.features.trackers.TrackersFragment
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
@@ -84,6 +85,11 @@ class DashboardFragment :
}
}
DashboardFeature.SingleEvent.NavigateToTrackersSingleEvent -> {
+ requireActivity().supportFragmentManager.commit {
+ add<TrackersFragment>(R.id.container)
+ setReorderingAllowed(true)
+ addToBackStack("dashboard")
+ }
}
}
}
@@ -110,6 +116,9 @@ class DashboardFragment :
it.findViewById<RelativeLayout>(R.id.apps_permissions).setOnClickListener {
viewModel.submitAction(DashboardFeature.Action.ShowAppsPermissions)
}
+ it.findViewById<RelativeLayout>(R.id.am_i_tracked).setOnClickListener {
+ viewModel.submitAction(DashboardFeature.Action.ShowTrackers)
+ }
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt
index 7e45049..9124f85 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt
@@ -36,8 +36,7 @@ class FakeLocationFeature(
coroutineScope: CoroutineScope,
reducer: Reducer<State, Effect>,
actor: Actor<State, Action, Effect>,
- singleEventProducer: SingleEventProducer<State, Action, Effect, SingleEvent>,
- private val locationApi: LocationApiDelegate
+ singleEventProducer: SingleEventProducer<State, Action, Effect, SingleEvent>
) : BaseFeature<FakeLocationFeature.State, FakeLocationFeature.Action, FakeLocationFeature.Effect, FakeLocationFeature.SingleEvent>(
initialState,
actor,
@@ -206,8 +205,7 @@ class FakeLocationFeature(
is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message)
else -> null
}
- },
- locationApi = locationApi
+ }
)
}
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt
index 4f9b602..4905dca 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt
@@ -36,17 +36,17 @@ class PermissionAppsAdapter(
val appName: TextView = view.findViewById(R.id.app_title)
@SuppressLint("UseSwitchCompatOrMaterialCode")
- val togglePermission: Switch = view.findViewById(R.id.togglePermission)
+ val togglePermission: Switch = view.findViewById(R.id.toggle)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PermissionViewHolder {
val view = LayoutInflater.from(parent.context)
- .inflate(R.layout.item_permission_apps, parent, false)
+ .inflate(R.layout.item_app_toggle, parent, false)
val holder = PermissionViewHolder(view)
holder.togglePermission.setOnCheckedChangeListener { _, isChecked ->
listener(dataSet[holder.adapterPosition].first, isChecked)
}
- view.findViewById<Switch>(R.id.togglePermission)
+ view.findViewById<Switch>(R.id.toggle)
return holder
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsAdapter.kt
new file mode 100644
index 0000000..ae236b9
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsAdapter.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.features.trackers
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Switch
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.dummy.Tracker
+
+class TrackerAppsAdapter(
+ private var tracker: Tracker,
+ private val listener: (Tracker, Boolean) -> Unit
+) :
+ RecyclerView.Adapter<TrackerAppsAdapter.TrackerViewHolder>() {
+
+ class TrackerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val titleView: TextView = view.findViewById(R.id.app_title)
+ @SuppressLint("UseSwitchCompatOrMaterialCode")
+ val toggleBlocker: Switch = view.findViewById(R.id.toggle)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackerViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_app_toggle, parent, false)
+ val holder = TrackerViewHolder(view)
+ holder.toggleBlocker.setOnClickListener {
+ if (it is Switch) {
+ listener(tracker, it.isChecked)
+ }
+ }
+ return holder
+ }
+
+ override fun onBindViewHolder(holder: TrackerViewHolder, position: Int) {
+ val app = tracker.trackedApps[position]
+ holder.titleView.text = app.appName
+ holder.toggleBlocker.isChecked = app.isEnabled
+ }
+
+ override fun getItemCount(): Int = tracker.trackedApps.size
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsFragment.kt
new file mode 100644
index 0000000..fff24dc
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackerAppsFragment.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.features.trackers
+
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import android.widget.Toast
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.flowmvi.MVIView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.common.NavToolbarFragment
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.collect
+
+class TrackerAppsFragment :
+ NavToolbarFragment(R.layout.fragment_tracker_apps),
+ MVIView<TrackersFeature.State, TrackersFeature.Action> {
+
+ private val viewModel: TrackersViewModel by viewModels()
+
+ private val TAG = "TrackerAppsFragment"
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ lifecycleScope.launchWhenStarted {
+ viewModel.trackersFeature.takeView(this, this@TrackerAppsFragment)
+ }
+ lifecycleScope.launchWhenStarted {
+ viewModel.trackersFeature.singleEvents.collect { event ->
+ when (event) {
+ is TrackersFeature.SingleEvent.ErrorEvent -> displayToast(event.error)
+ is TrackersFeature.SingleEvent.BlockerErrorEvent -> {
+ displayToast("Couldn't toggle")
+ // Re-render the current state to reset the switches.
+ render(viewModel.trackersFeature.state.value)
+ }
+ }
+ }
+ }
+ lifecycleScope.launchWhenStarted {
+ viewModel.submitAction(
+ TrackersFeature.Action.ObserveTracker(
+ requireArguments().getString(
+ "TRACKER"
+ )
+ )
+ )
+ }
+ }
+
+ private fun displayToast(message: String) {
+ Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT)
+ .show()
+ }
+
+ override fun getTitle(): String = getString(R.string.tracker)
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ view.findViewById<RecyclerView>(R.id.recylcer_view_tracker_apps)?.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ setHasFixedSize(true)
+ }
+ }
+
+ override fun render(state: TrackersFeature.State) {
+ Log.d(TAG, "render() called with: state = $state")
+ state.currentSelectedTracker?.let { tracker ->
+ view?.findViewById<RecyclerView>(R.id.recylcer_view_tracker_apps)?.adapter = TrackerAppsAdapter(tracker) { it, grant ->
+ viewModel.submitAction(
+ TrackersFeature.Action.ToggleTrackerAction(
+ it,
+ grant
+ )
+ )
+ }
+ getToolbar()?.title = tracker.name
+ }
+ }
+
+ override fun actions(): Flow<TrackersFeature.Action> = viewModel.actions
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt
new file mode 100644
index 0000000..cef069e
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersAdapter.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.features.trackers
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.dummy.Tracker
+
+class TrackersAdapter(
+ private var dataSet: List<Tracker> = emptyList(),
+ private val listener: (Tracker) -> Unit
+) :
+ RecyclerView.Adapter<TrackersAdapter.TrackerViewHolder>() {
+
+ class TrackerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val titleView: TextView = view as TextView
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackerViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_list_tracker, parent, false)
+ val holder = TrackerViewHolder(view)
+ holder.titleView.setOnClickListener { listener(dataSet[holder.adapterPosition]) }
+ return holder
+ }
+
+ override fun onBindViewHolder(holder: TrackerViewHolder, position: Int) {
+ val tracker = dataSet[position]
+ holder.titleView.text = tracker.name
+ }
+
+ override fun getItemCount(): Int = dataSet.size
+
+ fun setData(data: List<Tracker>) {
+ this.dataSet = data
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt
new file mode 100644
index 0000000..9400181
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFeature.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.features.trackers
+
+import android.util.Log
+import foundation.e.flowmvi.Actor
+import foundation.e.flowmvi.Reducer
+import foundation.e.flowmvi.SingleEventProducer
+import foundation.e.flowmvi.feature.BaseFeature
+import foundation.e.privacycentralapp.dummy.Tracker
+import foundation.e.privacycentralapp.dummy.TrackersDataSource
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+
+// Define a state machine for Tracker feature.
+class TrackersFeature(
+ initialState: State,
+ coroutineScope: CoroutineScope,
+ reducer: Reducer<State, Effect>,
+ actor: Actor<State, Action, Effect>,
+ singleEventProducer: SingleEventProducer<State, Action, Effect, SingleEvent>
+) : BaseFeature<TrackersFeature.State, TrackersFeature.Action, TrackersFeature.Effect, TrackersFeature.SingleEvent>(
+ initialState,
+ actor,
+ reducer,
+ coroutineScope,
+ { message -> Log.d("TrackersFeature", message) },
+ singleEventProducer
+) {
+ data class State(
+ val trackers: List<Tracker> = emptyList(),
+ val currentSelectedTracker: Tracker? = null
+ )
+
+ sealed class SingleEvent {
+ data class ErrorEvent(val error: String) : SingleEvent()
+ object BlockerErrorEvent : SingleEvent()
+ }
+
+ sealed class Action {
+ object ObserveTrackers : Action()
+ data class SetSelectedTracker(val tracker: Tracker) : Action()
+ data class ToggleTrackerAction(
+ val tracker: Tracker,
+ val grant: Boolean
+ ) : Action()
+ data class ObserveTracker(val tracker: String?) : Action()
+ }
+
+ sealed class Effect {
+ data class TrackersLoadedEffect(val trackers: List<Tracker>) : Effect()
+ data class TrackerSelectedEffect(val tracker: Tracker) : Effect()
+ data class TrackerToggleEffect(val result: Boolean) : Effect()
+ data class ErrorEffect(val message: String) : Effect()
+ data class TrackerLoadedEffect(val tracker: Tracker) : Effect()
+ }
+
+ companion object {
+ fun create(
+ initialState: State = State(),
+ coroutineScope: CoroutineScope
+ ) = TrackersFeature(
+ initialState, coroutineScope,
+ reducer = { state, effect ->
+ when (effect) {
+ is Effect.TrackersLoadedEffect -> State(effect.trackers)
+ is Effect.TrackerSelectedEffect -> state.copy(currentSelectedTracker = effect.tracker)
+ is Effect.ErrorEffect -> state
+ is Effect.TrackerToggleEffect -> {
+ state
+ }
+ is Effect.TrackerLoadedEffect -> {
+ state.copy(currentSelectedTracker = effect.tracker)
+ }
+ }
+ },
+ actor = { state, action ->
+ when (action) {
+ Action.ObserveTrackers -> TrackersDataSource.trackers.map {
+ Effect.TrackersLoadedEffect(
+ it
+ )
+ }
+ is Action.SetSelectedTracker -> flowOf(
+ Effect.TrackerSelectedEffect(
+ action.tracker
+ )
+ )
+
+ is Action.ToggleTrackerAction -> {
+ if (state.currentSelectedTracker != null) {
+ val result = TrackersDataSource.toggleTracker(
+ action.tracker,
+ action.grant
+ )
+ flowOf(Effect.TrackerToggleEffect(result))
+ } else {
+ flowOf(Effect.ErrorEffect("Can't toggle tracker"))
+ }
+ }
+ is Action.ObserveTracker -> {
+ if (action.tracker == null) {
+ flowOf(Effect.ErrorEffect("Null tracker id passed"))
+ } else {
+ val tracker = TrackersDataSource.getTracker(action.tracker)
+ if (tracker != null) {
+ flowOf(Effect.TrackerLoadedEffect(tracker))
+ } else {
+ flowOf(Effect.ErrorEffect("Can't find tracker with name ${action.tracker}"))
+ }
+ }
+ }
+ }
+ },
+ singleEventProducer = { _, _, effect ->
+ when (effect) {
+ is Effect.ErrorEffect -> SingleEvent.ErrorEvent(effect.message)
+ is Effect.TrackerToggleEffect -> {
+ if (!effect.result) SingleEvent.BlockerErrorEvent else null
+ }
+ else -> null
+ }
+ }
+ )
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
new file mode 100644
index 0000000..e3dc941
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.features.trackers
+
+import android.os.Bundle
+import android.view.View
+import androidx.core.os.bundleOf
+import androidx.fragment.app.add
+import androidx.fragment.app.commit
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.flowmvi.MVIView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.common.NavToolbarFragment
+import kotlinx.coroutines.flow.Flow
+
+class TrackersFragment :
+ NavToolbarFragment(R.layout.fragment_trackers),
+ MVIView<TrackersFeature.State, TrackersFeature.Action> {
+
+ private val viewModel: TrackersViewModel by viewModels()
+ private lateinit var trackersAdapter: TrackersAdapter
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ lifecycleScope.launchWhenStarted {
+ viewModel.trackersFeature.takeView(this, this@TrackersFragment)
+ }
+ lifecycleScope.launchWhenStarted {
+ viewModel.submitAction(TrackersFeature.Action.ObserveTrackers)
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ trackersAdapter = TrackersAdapter {
+ requireActivity().supportFragmentManager.commit {
+ val bundle = bundleOf("TRACKER" to it.name)
+ add<TrackerAppsFragment>(R.id.container, args = bundle)
+ setReorderingAllowed(true)
+ addToBackStack("trackers")
+ }
+ // viewModel.submitAction(TrackersFeature.Action.SetSelectedTracker(it))
+ }
+ view.findViewById<RecyclerView>(R.id.recylcer_view_trackers)?.apply {
+ layoutManager = LinearLayoutManager(requireContext())
+ setHasFixedSize(true)
+ adapter = trackersAdapter
+ }
+ }
+
+ override fun getTitle() = getString(R.string.trackers)
+
+ override fun render(state: TrackersFeature.State) {
+ trackersAdapter.setData(state.trackers)
+ }
+
+ override fun actions(): Flow<TrackersFeature.Action> = viewModel.actions
+}
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
new file mode 100644
index 0000000..ee89887
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersViewModel.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 E FOUNDATION
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package foundation.e.privacycentralapp.features.trackers
+
+import android.util.Log
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.launch
+
+class TrackersViewModel : ViewModel() {
+
+ private val _actions = MutableSharedFlow<TrackersFeature.Action>()
+ val actions = _actions.asSharedFlow()
+
+ val trackersFeature: TrackersFeature by lazy {
+ TrackersFeature.create(coroutineScope = viewModelScope)
+ }
+
+ fun submitAction(action: TrackersFeature.Action) {
+ Log.d("TrackersViewModel", "submitting action")
+ viewModelScope.launch {
+ _actions.emit(action)
+ }
+ }
+}
diff --git a/app/src/main/res/drawable/dummy_trackers_usage.png b/app/src/main/res/drawable/dummy_trackers_usage.png
new file mode 100644
index 0000000..9b7e090
--- /dev/null
+++ b/app/src/main/res/drawable/dummy_trackers_usage.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 7013496..2627a32 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
/> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_dashboard.xml b/app/src/main/res/layout/fragment_dashboard.xml
index dc79878..effd992 100644
--- a/app/src/main/res/layout/fragment_dashboard.xml
+++ b/app/src/main/res/layout/fragment_dashboard.xml
@@ -2,46 +2,46 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
>
- <include layout="@layout/topbar"/>
+ <include layout="@layout/topbar" />
<ProgressBar
android:id="@+id/loadingSpinner"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
android:indeterminate="true"
+ android:layout_gravity="center"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
/>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollContainer"
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:background="@color/white"
android:gravity="center_horizontal"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:orientation="vertical"
tools:context=".main.MainActivity"
>
<TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
android:gravity="center"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
- android:paddingTop="16dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
+ android:paddingTop="16dp"
android:text="@string/privacy_dashboard_info"
android:textColor="@color/black"
android:textSize="14sp"
@@ -49,91 +49,91 @@
<ImageView
android:id="@+id/togglePrivacyCentral"
- android:layout_width="96dp"
android:layout_height="96dp"
- android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
+ android:layout_marginTop="16dp"
+ android:layout_width="96dp"
android:src="@drawable/ic_privacy_toggle"
/>
<TextView
- android:id="@+id/tap_to_enable_quick_protection"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
android:drawableEnd="@drawable/ic_chevron_right_24dp"
android:fontFamily="sans-serif-medium"
android:gravity="center"
+ android:id="@+id/tap_to_enable_quick_protection"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
- android:paddingTop="16dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
+ android:paddingTop="16dp"
android:text="@string/tap_to_enable_quick_protection"
android:textColor="@color/black"
android:textSize="14sp"
/>
<ImageView
- android:layout_width="match_parent"
android:layout_height="160dp"
+ android:layout_width="match_parent"
android:src="@drawable/dummy_leakage_analytics"
/>
<TextView
+ android:gravity="center"
android:id="@+id/personal_leakag_info"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:gravity="center"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
android:text="@string/personal_leakage_info"
android:textColor="@color/black"
android:textSize="12sp"
/>
<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:background="#f9f9f9"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:orientation="vertical"
>
<RelativeLayout
android:id="@+id/am_i_tracked"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
- android:paddingTop="16dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
+ android:paddingTop="16dp"
>
<ImageView
android:id="@+id/am_i_tracked_icon"
- android:layout_width="36dp"
- android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:layout_height="36dp"
+ android:layout_width="36dp"
android:src="@drawable/ic_tracked"
/>
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toStartOf="@+id/am_i_tracked_chevron"
android:layout_toEndOf="@+id/am_i_tracked_icon"
+ android:layout_toStartOf="@+id/am_i_tracked_chevron"
+ android:layout_width="match_parent"
android:orientation="vertical"
- android:paddingStart="16dp"
android:paddingEnd="32dp"
+ android:paddingStart="16dp"
>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/am_i_tracked_title"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fontFamily="sans-serif-medium"
+ android:layout_width="match_parent"
android:text="@string/am_i_tracked_title"
android:textColor="@color/black"
android:textSize="16sp"
@@ -141,8 +141,8 @@
<TextView
android:id="@+id/am_i_tracked_subtitle"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:text="@string/am_i_tracked_subtitle"
android:textColor="@color/black"
android:textSize="14sp"
@@ -151,48 +151,48 @@
<ImageView
android:id="@+id/am_i_tracked_chevron"
- android:layout_width="24dp"
- android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:src="@drawable/ic_chevron_right_24dp"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/apps_permissions"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
- android:paddingTop="16dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
+ android:paddingTop="16dp"
>
<ImageView
android:id="@+id/apps_permissions_icon"
- android:layout_width="36dp"
- android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:layout_height="36dp"
+ android:layout_width="36dp"
android:src="@drawable/ic_apps_permissions"
/>
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toStartOf="@+id/apps_permissions_chevron"
android:layout_toEndOf="@+id/apps_permissions_icon"
+ android:layout_toStartOf="@+id/apps_permissions_chevron"
+ android:layout_width="match_parent"
android:orientation="vertical"
- android:paddingStart="16dp"
android:paddingEnd="32dp"
+ android:paddingStart="16dp"
>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/apps_permissions_title"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fontFamily="sans-serif-medium"
+ android:layout_width="match_parent"
android:text="@string/apps_permissions_title"
android:textColor="@color/black"
android:textSize="16sp"
@@ -200,8 +200,8 @@
<TextView
android:id="@+id/apps_permissions_subtitle"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:text="@string/apps_permissions_subtitle"
android:textColor="@color/black"
android:textSize="14sp"
@@ -210,48 +210,48 @@
<ImageView
android:id="@+id/apps_permissions_chevron"
- android:layout_width="24dp"
- android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:src="@drawable/ic_chevron_right_24dp"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/my_location"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
- android:paddingTop="16dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
+ android:paddingTop="16dp"
>
<ImageView
android:id="@+id/my_location_icon"
- android:layout_width="36dp"
- android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:layout_height="36dp"
+ android:layout_width="36dp"
android:src="@drawable/ic_my_location"
/>
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toStartOf="@+id/my_location_chevron"
android:layout_toEndOf="@+id/my_location_icon"
+ android:layout_toStartOf="@+id/my_location_chevron"
+ android:layout_width="match_parent"
android:orientation="vertical"
- android:paddingStart="16dp"
android:paddingEnd="32dp"
+ android:paddingStart="16dp"
>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/my_location_title"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fontFamily="sans-serif-medium"
+ android:layout_width="match_parent"
android:text="@string/my_location_title"
android:textColor="@color/black"
android:textSize="16sp"
@@ -259,8 +259,8 @@
<TextView
android:id="@+id/my_location_subtitle"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:text="@string/my_location_subtitle"
android:textColor="@color/black"
android:textSize="14sp"
@@ -269,48 +269,48 @@
<ImageView
android:id="@+id/my_location_chevron"
- android:layout_width="24dp"
- android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:src="@drawable/ic_chevron_right_24dp"
/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/internet_activity_privacy"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
android:paddingLeft="32dp"
- android:paddingTop="16dp"
android:paddingRight="32dp"
- android:paddingBottom="16dp"
+ android:paddingTop="16dp"
>
<ImageView
android:id="@+id/internet_activity_privacy_icon"
- android:layout_width="36dp"
- android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:layout_height="36dp"
+ android:layout_width="36dp"
android:src="@drawable/ic_internet_activity"
/>
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toStartOf="@+id/internet_activity_privacy_chevron"
android:layout_toEndOf="@+id/internet_activity_privacy_icon"
+ android:layout_toStartOf="@+id/internet_activity_privacy_chevron"
+ android:layout_width="match_parent"
android:orientation="vertical"
- android:paddingStart="16dp"
android:paddingEnd="32dp"
+ android:paddingStart="16dp"
>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/internet_activity_privacy_title"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fontFamily="sans-serif-medium"
+ android:layout_width="match_parent"
android:text="@string/internet_activity_privacy_title"
android:textColor="@color/black"
android:textSize="16sp"
@@ -318,8 +318,8 @@
<TextView
android:id="@+id/internet_activity_privacy_subtitle"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:text="@string/internet_activity_privacy_subtitle"
android:textColor="@color/black"
android:textSize="14sp"
@@ -328,10 +328,10 @@
<ImageView
android:id="@+id/internet_activity_privacy_chevron"
- android:layout_width="24dp"
- android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:src="@drawable/ic_chevron_right_24dp"
/>
</RelativeLayout>
diff --git a/app/src/main/res/layout/fragment_fake_location.xml b/app/src/main/res/layout/fragment_fake_location.xml
index 40324a1..d60513b 100644
--- a/app/src/main/res/layout/fragment_fake_location.xml
+++ b/app/src/main/res/layout/fragment_fake_location.xml
@@ -8,7 +8,7 @@
android:layout_width="match_parent"
>
- <include layout="@layout/topbar"/>
+ <include layout="@layout/topbar" />
<androidx.core.widget.NestedScrollView
android:layout_height="match_parent"
@@ -18,9 +18,9 @@
<LinearLayout
android:layout_height="match_parent"
+ android:layout_marginBottom="32dp"
android:layout_width="match_parent"
android:orientation="vertical"
- android:layout_marginBottom="32dp"
tools:context=".main.MainActivity"
>
@@ -29,9 +29,9 @@
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:paddingTop="16dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
+ android:paddingTop="16dp"
android:text="@string/fake_location_info"
android:textColor="@color/black"
android:textSize="14sp"
diff --git a/app/src/main/res/layout/fragment_internet_activity_policy.xml b/app/src/main/res/layout/fragment_internet_activity_policy.xml
index 7a5d8b5..c3021df 100644
--- a/app/src/main/res/layout/fragment_internet_activity_policy.xml
+++ b/app/src/main/res/layout/fragment_internet_activity_policy.xml
@@ -2,23 +2,23 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:background="@color/white"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
>
- <include layout="@layout/topbar"/>
+ <include layout="@layout/topbar" />
<androidx.core.widget.NestedScrollView
- android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="32dp"
+ android:layout_width="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingRight="32dp"
@@ -27,9 +27,9 @@
<TextView
android:id="@+id/internet_activity_privacy_info"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:paddingTop="16dp"
android:text="@string/internet_activity_privacy_info"
android:textColor="@color/black"
@@ -37,23 +37,23 @@
/>
<TextView
- android:id="@+id/learn_more_internet_activity_privacy_info"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical"
+ android:id="@+id/learn_more_internet_activity_privacy_info"
+ android:layout_height="48dp"
+ android:layout_width="wrap_content"
android:text="@string/learn_more"
android:textColor="#007fff"
android:textSize="14sp"
/>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/my_internet_activity_header"
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:fontFamily="sans-serif-medium"
- android:paddingTop="16dp"
+ android:layout_width="wrap_content"
android:paddingBottom="8dp"
+ android:paddingTop="16dp"
android:text="@string/internet_activity_privacy_title"
android:textColor="@color/black"
android:textSize="14sp"
@@ -61,37 +61,41 @@
<RadioGroup
android:id="@+id/internet_activity_privacy_choices"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:orientation="vertical"
>
<foundation.e.privacycentralapp.common.RightRadioButton
android:id="@+id/radio_use_real_ip"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:text="@string/use_real_ip"
android:textSize="16sp"
/>
+
<TextView
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:text="@string/i_can_be_tracked"
- android:textSize="14sp"/>
+ android:textSize="14sp"
+ />
<foundation.e.privacycentralapp.common.RightRadioButton
android:id="@+id/radio_use_hidden_ip"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_width="match_parent"
android:text="@string/hidden_ip"
android:textSize="16sp"
- android:layout_marginTop="8dp"
/>
+
<TextView
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:text="@string/i_am_anonymous"
- android:textSize="14sp"/>
+ android:textSize="14sp"
+ />
</RadioGroup>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
diff --git a/app/src/main/res/layout/fragment_permission_apps.xml b/app/src/main/res/layout/fragment_permission_apps.xml
index 65f4169..db61e93 100644
--- a/app/src/main/res/layout/fragment_permission_apps.xml
+++ b/app/src/main/res/layout/fragment_permission_apps.xml
@@ -2,37 +2,45 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:background="@color/white"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
>
- <include layout="@layout/topbar"/>
+ <include layout="@layout/topbar" />
- <LinearLayout
- android:layout_width="match_parent"
+ <androidx.core.widget.NestedScrollView
android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context=".main.MainActivity"
+ android:layout_width="match_parent"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
- <TextView
- android:id="@+id/permission_control"
+ <LinearLayout
+ android:layout_height="match_parent"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:textColor="@color/black"
- android:textSize="14sp"
- />
+ android:orientation="vertical"
+ tools:context=".main.MainActivity"
+ >
- <androidx.recyclerview.widget.RecyclerView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:listitem="@layout/item_permission_apps"
- android:id="@+id/recylcer_view_permission_apps"/>
- </LinearLayout>
+ <TextView
+ android:id="@+id/permission_control"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
+ android:paddingLeft="32dp"
+ android:paddingRight="32dp"
+ android:paddingTop="16dp"
+ android:textColor="@color/black"
+ android:textSize="14sp"
+ />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recylcer_view_permission_apps"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ tools:listitem="@layout/item_app_toggle"
+ />
+ </LinearLayout>
+ </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_permissions.xml b/app/src/main/res/layout/fragment_permissions.xml
index a452570..7ca4b43 100644
--- a/app/src/main/res/layout/fragment_permissions.xml
+++ b/app/src/main/res/layout/fragment_permissions.xml
@@ -2,16 +2,22 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:background="@color/white"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
>
- <include layout="@layout/topbar"/>
+ <include layout="@layout/topbar" />
+
+ <androidx.core.widget.NestedScrollView
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ >
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
android:orientation="vertical"
android:paddingLeft="32dp"
android:paddingRight="32dp"
@@ -20,9 +26,9 @@
<TextView
android:id="@+id/permission_control"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:paddingTop="16dp"
android:text="@string/permission_control_info"
android:textColor="@color/black"
@@ -30,20 +36,22 @@
/>
<TextView
- android:id="@+id/learn_more_permissions"
- android:layout_width="wrap_content"
- android:layout_height="48dp"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical"
+ android:id="@+id/learn_more_permissions"
+ android:layout_height="48dp"
+ android:layout_width="wrap_content"
android:text="@string/learn_more"
android:textColor="#007fff"
android:textSize="14sp"
/>
<androidx.recyclerview.widget.RecyclerView
- android:layout_width="match_parent"
+ android:id="@+id/recylcer_view_permissions"
android:layout_height="match_parent"
+ android:layout_width="match_parent"
tools:listitem="@layout/item_permission"
- android:id="@+id/recylcer_view_permissions"/>
+ />
</LinearLayout>
+ </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_quick_protection.xml b/app/src/main/res/layout/fragment_quick_protection.xml
index d57a101..569f9b1 100644
--- a/app/src/main/res/layout/fragment_quick_protection.xml
+++ b/app/src/main/res/layout/fragment_quick_protection.xml
@@ -1,59 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:background="@color/white"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
>
- <include layout="@layout/topbar"/>
+ <include layout="@layout/topbar" />
- <LinearLayout
- android:layout_width="match_parent"
+ <androidx.core.widget.NestedScrollView
android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginBottom="56dp"
- tools:context=".main.MainActivity"
+ android:layout_width="match_parent"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
- <TextView
- android:id="@+id/quick_protection_info"
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_marginBottom="56dp"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:paddingTop="16dp"
- android:text="@string/quick_protection_info"
- android:textColor="@color/black"
- android:textSize="14sp"
- />
+ android:orientation="vertical"
+ tools:context=".main.MainActivity"
+ >
+
+ <TextView
+ android:id="@+id/quick_protection_info"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingLeft="32dp"
+ android:paddingRight="32dp"
+ android:paddingTop="16dp"
+ android:text="@string/quick_protection_info"
+ android:textColor="@color/black"
+ android:textSize="14sp"
+ />
+
+ <TextView
+ android:fontFamily="sans-serif-medium"
+ android:id="@+id/quick_protection_settings_list"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
+ android:paddingLeft="32dp"
+ android:paddingRight="32dp"
+ android:paddingTop="16dp"
+ android:text="@string/quick_protection_settings_list"
+ android:textColor="@color/black"
+ android:textSize="14sp"
+ />
+ </LinearLayout>
+
+ </androidx.core.widget.NestedScrollView>
- <TextView
- android:id="@+id/quick_protection_settings_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
- android:paddingLeft="32dp"
- android:paddingRight="32dp"
- android:fontFamily="sans-serif-medium"
- android:text="@string/quick_protection_settings_list"
- android:textColor="@color/black"
- android:textSize="14sp"
- />
- </LinearLayout>
<TextView
- android:layout_width="wrap_content"
+ android:fontFamily="sans-serif-medium"
+ android:gravity="center_vertical|end"
+ android:id="@+id/learn_more"
+ android:layout_gravity="bottom|end"
android:layout_height="56dp"
- android:paddingRight="32dp"
+ android:layout_width="wrap_content"
android:paddingLeft="32dp"
- android:gravity="center_vertical|right"
- android:id="@+id/learn_more"
+ android:paddingRight="32dp"
android:text="@string/learn_more"
android:textColor="#007fff"
android:textSize="14sp"
- android:fontFamily="sans-serif-medium"
- android:layout_gravity="bottom|right"/>
+ />
</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_tracker_apps.xml b/app/src/main/res/layout/fragment_tracker_apps.xml
new file mode 100644
index 0000000..3341d95
--- /dev/null
+++ b/app/src/main/res/layout/fragment_tracker_apps.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:background="@color/white"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ >
+
+ <include layout="@layout/topbar" />
+
+ <androidx.core.widget.NestedScrollView
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ >
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ tools:context=".main.MainActivity"
+ >
+
+ <TextView
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingBottom="16dp"
+ android:paddingLeft="32dp"
+ android:paddingRight="32dp"
+ android:paddingTop="16dp"
+ android:text="@string/enable_disable_tracker_info"
+ android:textColor="@color/black"
+ android:textSize="14sp"
+ />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recylcer_view_tracker_apps"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ tools:listitem="@layout/item_app_toggle"
+ />
+ </LinearLayout>
+ </androidx.core.widget.NestedScrollView>
+</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_trackers.xml b/app/src/main/res/layout/fragment_trackers.xml
new file mode 100644
index 0000000..591b2b6
--- /dev/null
+++ b/app/src/main/res/layout/fragment_trackers.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:background="@color/white"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ >
+
+ <include layout="@layout/topbar" />
+
+ <androidx.core.widget.NestedScrollView
+ android:layout_height="match_parent"
+ android:layout_marginBottom="32dp"
+ android:layout_width="match_parent"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ >
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="32dp"
+ android:paddingRight="32dp"
+ tools:context=".main.MainActivity"
+ >
+
+ <TextView
+ android:id="@+id/trackers_info"
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingTop="16dp"
+ android:text="@string/manage_trackers_info"
+ android:textColor="@color/black"
+ android:textSize="14sp"
+ />
+
+ <TextView
+ android:fontFamily="sans-serif-medium"
+ android:gravity="center_vertical"
+ android:id="@+id/learn_more_trackers_info"
+ android:layout_height="48dp"
+ android:layout_width="wrap_content"
+ android:text="@string/learn_more"
+ android:textColor="#007fff"
+ android:textSize="14sp"
+ />
+
+ <ImageView
+ android:layout_height="300dp"
+ android:layout_width="wrap_content"
+ android:scaleType="centerInside"
+ android:src="@drawable/dummy_trackers_usage"
+ />
+
+ <TextView
+ android:layout_gravity="center_horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:paddingTop="16dp"
+ android:text="@string/following_trackers_in_use"
+ android:textColor="@color/black"
+ android:textSize="16sp"
+ />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recylcer_view_trackers"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ tools:listitem="@layout/item_list_tracker"
+ />
+ </LinearLayout>
+ </androidx.core.widget.NestedScrollView>
+</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_permission_apps.xml b/app/src/main/res/layout/item_app_toggle.xml
index aec8fec..d0f565f 100644
--- a/app/src/main/res/layout/item_permission_apps.xml
+++ b/app/src/main/res/layout/item_app_toggle.xml
@@ -2,43 +2,43 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_permission_apps"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="16dp"
+ android:layout_width="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
+ android:paddingTop="16dp"
>
<ImageView
android:id="@+id/app_icon"
- android:layout_width="36dp"
- android:layout_height="36dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:layout_height="36dp"
+ android:layout_width="36dp"
android:src="@drawable/ic_facebook"
/>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/app_title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
android:layout_centerVertical="true"
- android:layout_toStartOf="@+id/togglePermission"
+ android:layout_height="wrap_content"
android:layout_toEndOf="@+id/app_icon"
- android:fontFamily="sans-serif-medium"
- android:paddingStart="32dp"
+ android:layout_toStartOf="@+id/toggle"
+ android:layout_width="match_parent"
android:paddingEnd="32dp"
+ android:paddingStart="32dp"
android:textColor="@color/black"
android:textSize="16sp"
tools:text="Body sensor"
/>
<Switch
- android:id="@+id/togglePermission"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:id="@+id/toggle"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
/>
</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_list_tracker.xml b/app/src/main/res/layout/item_list_tracker.xml
new file mode 100644
index 0000000..1b5ecc2
--- /dev/null
+++ b/app/src/main/res/layout/item_list_tracker.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ 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/>.
+ -->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:fontFamily="sans-serif-medium"
+ android:id="@+id/tracker_title"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:textColor="@color/accent"
+ android:textSize="16sp"
+ tools:text="Google Crashlytics"
+ /> \ No newline at end of file
diff --git a/app/src/main/res/layout/item_permission.xml b/app/src/main/res/layout/item_permission.xml
index 8f54f64..66d4213 100644
--- a/app/src/main/res/layout/item_permission.xml
+++ b/app/src/main/res/layout/item_permission.xml
@@ -17,57 +17,57 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_permission"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="16dp"
+ android:layout_width="match_parent"
android:paddingBottom="16dp"
+ android:paddingTop="16dp"
>
<ImageView
android:id="@+id/permission_icon"
- android:layout_width="24dp"
- android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
android:src="@drawable/ic_body_monitor"
/>
<LinearLayout
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_toStartOf="@+id/chevron"
android:layout_toEndOf="@+id/permission_icon"
+ android:layout_toStartOf="@+id/chevron"
+ android:layout_width="match_parent"
android:orientation="vertical"
- android:paddingStart="32dp"
android:paddingEnd="32dp"
+ android:paddingStart="32dp"
>
<TextView
+ android:fontFamily="sans-serif-medium"
android:id="@+id/permission_title"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:fontFamily="sans-serif-medium"
- tools:text="Body sensor"
+ android:layout_width="match_parent"
android:textColor="@color/black"
android:textSize="16sp"
+ tools:text="Body sensor"
/>
<TextView
android:id="@+id/permission_count"
- android:layout_width="match_parent"
android:layout_height="wrap_content"
- tools:text="3 of 8 apps allowed"
+ android:layout_width="match_parent"
android:textSize="14sp"
+ tools:text="3 of 8 apps allowed"
/>
</LinearLayout>
<ImageView
android:id="@+id/chevron"
- android:layout_width="24dp"
- android:layout_height="24dp"
- android:padding="4dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
+ android:padding="4dp"
android:src="@drawable/ic_chevron_right_24dp"
/>
</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/topbar.xml b/app/src/main/res/layout/topbar.xml
index 9142d79..a493b3b 100644
--- a/app/src/main/res/layout/topbar.xml
+++ b/app/src/main/res/layout/topbar.xml
@@ -18,20 +18,20 @@
-->
<com.google.android.material.appbar.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto"
app:elevation="0dp"
>
<com.google.android.material.appbar.MaterialToolbar
android:background="@color/white"
- android:id="@+id/toolbar"
- app:titleCentered="true"
android:elevation="0dp"
+ android:id="@+id/toolbar"
android:layout_height="?android:attr/actionBarSize"
android:layout_width="match_parent"
+ app:titleCentered="true"
tools:layout_height="56dp"
/>
</com.google.android.material.appbar.AppBarLayout>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index f8c6127..4f45122 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -7,4 +7,6 @@
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
+
+ <color name="accent">@lineageos.platform:color/color_default_accent</color>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fd24223..3105ddb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -42,5 +42,10 @@
<string name="quick_protection">Quick Protection</string>
<string name="privacy_dashboard">Privacy Dashboard</string>
<string name="click_to_learn_more">Click to learn more</string>
- <string name="apps_permissions">\"Apps Permission\"</string>
+ <string name="apps_permissions">Apps Permission</string>
+ <string name="trackers">Trackers</string>
+ <string name="manage_trackers_info">See trackers usage over time and manage trackers available in applications</string>
+ <string name="following_trackers_in_use">Following trackers are in use</string>
+ <string name="enable_disable_tracker_info">Enable or disable this tracker for the following apps</string>
+ <string name="tracker">Tracker</string>
</resources> \ No newline at end of file
diff --git a/flow-mvi/src/main/java/foundation/e/flowmvi/feature/BaseFeature.kt b/flow-mvi/src/main/java/foundation/e/flowmvi/feature/BaseFeature.kt
index 8dec0c4..c60373f 100644
--- a/flow-mvi/src/main/java/foundation/e/flowmvi/feature/BaseFeature.kt
+++ b/flow-mvi/src/main/java/foundation/e/flowmvi/feature/BaseFeature.kt
@@ -120,7 +120,7 @@ open class BaseFeature<State : Any, in Action : Any, in Effect : Any, SingleEven
) {
onEach { action ->
callerCoroutineScope.launch {
- logger.invoke("Received action $action")
+ logger.invoke("Received action $action $this")
actor.invoke(_state.value, action)
.onEach { effect ->
mutex.withLock {
diff --git a/scripts/sign_and_push.sh b/scripts/sign_and_push.sh
index 240f96a..035a47b 100755
--- a/scripts/sign_and_push.sh
+++ b/scripts/sign_and_push.sh
@@ -3,16 +3,15 @@
## This script is used for signing the apk with the platform keys and pushing it into System partition.
## Used for testing purposes.
-./gradlew assembleDebug
-rm PrivacyCentral.apk
-wait ${!}
-apksigner sign --key lineage_keys/platform.pk8 --cert lineage_keys/target_product_security_platform.x509.pem --out PrivacyCentral.apk app/build/outputs/apk/e/debug/app-e-debug.apk
-wait ${!}
+## Note: It is used only to build /e/ OS variant build.
+
+./gradlew assembleEDebug
adb root
wait ${!}
adb devices
wait ${!}
-adb install -r PrivacyCentral.apk
+adb install -r app/build/outputs/apk/e/debug/PrivacyCentral-e-debug-1.0.0-alpha.apk
wait ${!}
adb remount && adb push privapp-permissions-foundation.e.privacycentralapp.xml system/etc/permissions
-wait ${!} \ No newline at end of file
+wait ${!}
+adb shell am start -n "foundation.e.privacycentralapp.e/foundation.e.privacycentralapp.main.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER