summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/build.gradle4
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt67
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/NavToolbarFragment.kt1
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackersPeriodicStatistics.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/domain/usecases/TrackersStatisticsUseCase.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt8
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt2
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt4
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt51
-rw-r--r--app/src/main/res/drawable/ic_legend_blocked.xml21
-rw-r--r--app/src/main/res/drawable/ic_legend_leaked.xml21
-rw-r--r--app/src/main/res/layout/fragment_dashboard.xml49
-rw-r--r--app/src/main/res/layout/trackers_item_graph.xml49
-rw-r--r--app/src/main/res/layout/widget.xml522
-rw-r--r--app/src/main/res/values/strings.xml2
-rw-r--r--build.gradle6
16 files changed, 676 insertions, 141 deletions
diff --git a/app/build.gradle b/app/build.gradle
index bbbb70b..dbbfa47 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -112,8 +112,8 @@ dependencies {
//googleImplementation project(":privacymodulesgoogle")
// include the e specific version of the modules, just for the e flavor
- implementation 'foundation.e:privacymodule.trackerfilter:0.5.1'
- implementation 'foundation.e:privacymodule.api:0.6.0'
+ implementation 'foundation.e:privacymodule.trackerfilter:0.6.0'
+ implementation 'foundation.e:privacymodule.api:1.0.0'
e29Implementation 'foundation.e:privacymodule.e-29:0.4.2'
e30Implementation 'foundation.e:privacymodule.e-30:0.4.2'
implementation 'foundation.e:privacymodule.tor:0.2.2'
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt b/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt
index 929d838..aba3a95 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/GraphHolder.kt
@@ -19,9 +19,14 @@ package foundation.e.privacycentralapp.common
import android.content.Context
import android.graphics.Canvas
+import android.text.Spannable
+import android.text.SpannableStringBuilder
+import android.text.style.DynamicDrawableSpan
+import android.text.style.ImageSpan
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
+import androidx.core.text.toSpannable
import androidx.core.view.isVisible
import com.github.mikephil.charting.charts.BarChart
import com.github.mikephil.charting.components.MarkerView
@@ -37,7 +42,7 @@ import foundation.e.privacycentralapp.R
import foundation.e.privacycentralapp.extensions.dpToPxF
class GraphHolder(val barChart: BarChart, val context: Context, val isMarkerAbove: Boolean = true) {
- var data = emptyList<Int>()
+ var data = emptyList<Pair<Int, Int>>()
set(value) {
field = value
refreshDataSet()
@@ -80,7 +85,17 @@ class GraphHolder(val barChart: BarChart, val context: Context, val isMarkerAbov
setOnChartValueSelectedListener(object : OnChartValueSelectedListener {
override fun onValueSelected(e: Entry?, h: Highlight?) {
- h?.let { periodMarker.setLabel(labels.getOrNull(it.x.toInt())) }
+ h?.let {
+ val index = it.x.toInt()
+ if (index > 0 &&
+ index < labels.size &&
+ index < this@GraphHolder.data.size
+ ) {
+ val period = labels[index]
+ val (blocked, leaked) = this@GraphHolder.data[index]
+ periodMarker.setLabel(period, blocked, leaked)
+ }
+ }
isHighlighted = true
refreshDataSet()
}
@@ -95,18 +110,31 @@ class GraphHolder(val barChart: BarChart, val context: Context, val isMarkerAbov
private fun refreshDataSet() {
val trackersDataSet = BarDataSet(
- data.mapIndexed { index, value -> BarEntry(index.toFloat(), value.toFloat()) },
+ data.mapIndexed { index, value ->
+ BarEntry(
+ index.toFloat(),
+ floatArrayOf(value.first.toFloat(), value.second.toFloat())
+ )
+ },
""
).apply {
- color = ContextCompat.getColor(
- context,
- if (isHighlighted) R.color.blue_unselected else R.color.accent
+
+ val blockedColor = ContextCompat.getColor(context, R.color.accent)
+ val leakedColor = ContextCompat.getColor(context, R.color.red_off)
+
+ // ColorUtils.setAlphaComponent()
+ colors = listOf(
+ blockedColor,
+ // if (isHighlighted) R.color.blue_unselected else R.color.accent
+ leakedColor
)
+
setDrawValues(false)
- highLightColor = ContextCompat.getColor(
- context, R.color.accent
- )
- highLightAlpha = 255
+
+ // highLightColor = ContextCompat.getColor(
+ // context, R.color.accent
+ // )
+ // highLightAlpha = 255
}
barChart.data = BarData(trackersDataSet)
@@ -162,8 +190,23 @@ class PeriodMarkerView(context: Context, private val isMarkerAbove: Boolean = tr
}
}
- fun setLabel(label: String?) {
- findViewById<TextView>(R.id.label).text = label
+ fun setLabel(period: String, blocked: Int, leaked: Int) {
+ val span = SpannableStringBuilder(period)
+ span.append(": $blocked ")
+ span.setSpan(
+ ImageSpan(context, R.drawable.ic_legend_blocked, DynamicDrawableSpan.ALIGN_BASELINE),
+ span.length - 1,
+ span.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ span.append(" $leaked ")
+ span.setSpan(
+ ImageSpan(context, R.drawable.ic_legend_leaked, DynamicDrawableSpan.ALIGN_BASELINE),
+ span.length - 1,
+ span.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ findViewById<TextView>(R.id.label).text = span.toSpannable()
}
override fun refreshContent(e: Entry?, highlight: Highlight?) {
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/NavToolbarFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/common/NavToolbarFragment.kt
index c28c871..6955405 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/common/NavToolbarFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/NavToolbarFragment.kt
@@ -19,7 +19,6 @@ package foundation.e.privacycentralapp.common
import androidx.annotation.LayoutRes
import com.google.android.material.appbar.MaterialToolbar
-import foundation.e.privacycentralapp.R
abstract class NavToolbarFragment(@LayoutRes contentLayoutId: Int) : ToolbarFragment(contentLayoutId) {
diff --git a/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackersPeriodicStatistics.kt b/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackersPeriodicStatistics.kt
index 8a27d6d..b3a6ade 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackersPeriodicStatistics.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/domain/entities/TrackersPeriodicStatistics.kt
@@ -18,7 +18,7 @@
package foundation.e.privacycentralapp.domain.entities
data class TrackersPeriodicStatistics(
- val calls: List<Int>,
+ val callsBlockedNLeaked: List<Pair<Int, Int>>,
val periods: List<String>,
val trackersCount: Int
)
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 69dd0d8..4262055 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
@@ -53,7 +53,7 @@ class TrackersStatisticsUseCase(
fun getDayStatistics(): Pair<TrackersPeriodicStatistics, Int> {
return TrackersPeriodicStatistics(
- calls = trackTrackersPrivacyModule.getPastDayTrackersCalls(),
+ callsBlockedNLeaked = trackTrackersPrivacyModule.getPastDayTrackersCalls(),
periods = buildDayLabels(),
trackersCount = trackTrackersPrivacyModule.getPastDayTrackersCount()
) to trackTrackersPrivacyModule.getTrackersCount()
@@ -107,17 +107,17 @@ class TrackersStatisticsUseCase(
return with(trackTrackersPrivacyModule) {
Triple(
TrackersPeriodicStatistics(
- calls = getPastDayTrackersCalls(),
+ callsBlockedNLeaked = getPastDayTrackersCalls(),
periods = buildDayLabels(),
trackersCount = getPastDayTrackersCount()
),
TrackersPeriodicStatistics(
- calls = getPastMonthTrackersCalls(),
+ callsBlockedNLeaked = getPastMonthTrackersCalls(),
periods = buildMonthLabels(),
trackersCount = getPastMonthTrackersCount()
),
TrackersPeriodicStatistics(
- calls = getPastYearTrackersCalls(),
+ callsBlockedNLeaked = getPastYearTrackersCalls(),
periods = buildYearLabels(),
trackersCount = getPastYearTrackersCount()
)
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 87f5e42..8a4ee54 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
@@ -57,7 +57,7 @@ class DashboardFeature(
// val graphData
val trackersCount: Int? = null,
val activeTrackersCount: Int? = null,
- val dayStatistics: List<Int>? = null,
+ val dayStatistics: List<Pair<Int, Int>>? = null,
val dayLabels: List<String>? = null
)
@@ -84,7 +84,7 @@ class DashboardFeature(
data class UpdateStateEffect(val isEnabled: Boolean) : Effect()
data class IpScramblingModeUpdatedEffect(val mode: InternetPrivacyMode) : Effect()
data class TrackersStatisticsUpdatedEffect(
- val dayStatistics: List<Int>,
+ val dayStatistics: List<Pair<Int, Int>>,
val dayLabels: List<String>,
val dayTrackersCount: Int,
val trackersCount: Int
@@ -151,7 +151,7 @@ class DashboardFeature(
trackersStatisticsUseCase.getDayStatistics().let {
(dayStatistics, trackersCount) ->
Effect.TrackersStatisticsUpdatedEffect(
- dayStatistics = dayStatistics.calls,
+ dayStatistics = dayStatistics.callsBlockedNLeaked,
dayLabels = dayStatistics.periods,
dayTrackersCount = dayStatistics.trackersCount,
trackersCount = trackersCount
@@ -176,7 +176,7 @@ class DashboardFeature(
trackersStatisticsUseCase.getDayStatistics().let {
(dayStatistics, trackersCount) ->
Effect.TrackersStatisticsUpdatedEffect(
- dayStatistics = dayStatistics.calls,
+ dayStatistics = dayStatistics.callsBlockedNLeaked,
dayLabels = dayStatistics.periods,
dayTrackersCount = dayStatistics.trackersCount,
trackersCount = trackersCount
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 dec3234..51dee3d 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
@@ -217,7 +217,7 @@ class DashboardFragment :
)
)
- if (state.dayStatistics?.all { it == 0 } == true) {
+ if (state.dayStatistics?.all { it.first == 0 && it.second == 0 } == true) {
binding.graph.visibility = View.INVISIBLE
binding.graphLegend.isVisible = false
binding.graphEmpty.isVisible = true
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
index c0212a5..893f4ba 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/trackers/TrackersFragment.kt
@@ -137,13 +137,13 @@ class TrackersFragment :
graphHolder: GraphHolder,
graphBinding: TrackersItemGraphBinding
) {
- if (statistics.calls.all { it == 0 }) {
+ if (statistics.callsBlockedNLeaked.all { it.first == 0 && it.second == 0 }) {
graphBinding.graph.visibility = View.INVISIBLE
graphBinding.graphEmpty.isVisible = true
} else {
graphBinding.graph.isVisible = true
graphBinding.graphEmpty.isVisible = false
- graphHolder.data = statistics.calls
+ graphHolder.data = statistics.callsBlockedNLeaked
graphHolder.labels = statistics.periods
graphBinding.trackersCountLabel.text =
getString(R.string.trackers_count_label, statistics.trackersCount)
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 443683a..2529f6c 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/widget/WidgetUI.kt
@@ -39,7 +39,7 @@ data class State(
val isAllTrackersBlocked: Boolean = false,
val locationMode: LocationMode = LocationMode.REAL_LOCATION,
val internetPrivacyMode: InternetPrivacyMode = InternetPrivacyMode.REAL_IP,
- val dayStatistics: List<Int> = emptyList(),
+ val dayStatistics: List<Pair<Int, Int>> = emptyList(),
val activeTrackersCount: Int = 0,
) {
val isTrackersDenied get() = isQuickPrivacyEnabled && isAllTrackersBlocked
@@ -123,23 +123,33 @@ fun render(
setViewVisibility(R.id.state_ip_address_loader, if (loading) View.VISIBLE else View.GONE)
- if (state.dayStatistics.all { it == 0 }) {
+ if (state.dayStatistics.all { it.first == 0 && it.second == 0 }) {
setViewVisibility(R.id.graph, View.GONE)
setViewVisibility(R.id.graph_legend, View.GONE)
setViewVisibility(R.id.graph_empty, View.VISIBLE)
+ setViewVisibility(R.id.graph_legend_values, View.GONE)
} else {
setViewVisibility(R.id.graph, View.VISIBLE)
setViewVisibility(R.id.graph_legend, View.VISIBLE)
setViewVisibility(R.id.graph_empty, View.GONE)
+ setViewVisibility(R.id.graph_legend_values, View.VISIBLE)
val graphHeightPx = 26.dpToPxF(context)
val maxValue =
- state.dayStatistics.maxOrNull().let { if (it == null || it == 0) 1 else it }
+ state.dayStatistics
+ .map { it.first + it.second }
+ .maxOrNull()
+ .let { if (it == null || it == 0) 1 else it }
val ratio = graphHeightPx / maxValue
- state.dayStatistics.zip(barIds).forEach { (value, viewId) ->
- val topPadding = graphHeightPx - value * ratio
- setViewPadding(viewId, 0, topPadding.toInt(), 0, 0)
+ state.dayStatistics.forEachIndexed { index, (blocked, leaked) ->
+ // blocked (the bar below)
+ val middlePadding = graphHeightPx - blocked * ratio
+ setViewPadding(blockedBarIds[index], 0, middlePadding.toInt(), 0, 0)
+
+ // leacked (the bar above)
+ val topPadding = graphHeightPx - (blocked + leaked) * ratio
+ setViewPadding(leakedBarIds[index], 0, topPadding.toInt(), 0, 0)
}
setTextViewText(
@@ -155,7 +165,7 @@ fun render(
appWidgetManager.updateAppWidget(ComponentName(context, Widget::class.java), views)
}
-private val barIds = listOf(
+private val blockedBarIds = listOf(
R.id.widget_graph_bar_0,
R.id.widget_graph_bar_1,
R.id.widget_graph_bar_2,
@@ -181,3 +191,30 @@ private val barIds = listOf(
R.id.widget_graph_bar_22,
R.id.widget_graph_bar_23
)
+
+private val leakedBarIds = listOf(
+ R.id.widget_leaked_graph_bar_0,
+ R.id.widget_leaked_graph_bar_1,
+ R.id.widget_leaked_graph_bar_2,
+ R.id.widget_leaked_graph_bar_3,
+ R.id.widget_leaked_graph_bar_4,
+ R.id.widget_leaked_graph_bar_5,
+ R.id.widget_leaked_graph_bar_6,
+ R.id.widget_leaked_graph_bar_7,
+ R.id.widget_leaked_graph_bar_8,
+ R.id.widget_leaked_graph_bar_9,
+ R.id.widget_leaked_graph_bar_10,
+ R.id.widget_leaked_graph_bar_11,
+ R.id.widget_leaked_graph_bar_12,
+ R.id.widget_leaked_graph_bar_13,
+ R.id.widget_leaked_graph_bar_14,
+ R.id.widget_leaked_graph_bar_15,
+ R.id.widget_leaked_graph_bar_16,
+ R.id.widget_leaked_graph_bar_17,
+ R.id.widget_leaked_graph_bar_18,
+ R.id.widget_leaked_graph_bar_19,
+ R.id.widget_leaked_graph_bar_20,
+ R.id.widget_leaked_graph_bar_21,
+ R.id.widget_leaked_graph_bar_22,
+ R.id.widget_leaked_graph_bar_23
+)
diff --git a/app/src/main/res/drawable/ic_legend_blocked.xml b/app/src/main/res/drawable/ic_legend_blocked.xml
new file mode 100644
index 0000000..15f8c56
--- /dev/null
+++ b/app/src/main/res/drawable/ic_legend_blocked.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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/>.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+ <solid android:color="@color/accent"/>
+ <size android:width="12dp" android:height="12dp" />
+</shape> \ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_legend_leaked.xml b/app/src/main/res/drawable/ic_legend_leaked.xml
new file mode 100644
index 0000000..a96501f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_legend_leaked.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ 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/>.
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+ <solid android:color="@color/red_off"/>
+ <size android:width="12dp" android:height="12dp" />
+</shape> \ 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 53ec617..ff64733 100644
--- a/app/src/main/res/layout/fragment_dashboard.xml
+++ b/app/src/main/res/layout/fragment_dashboard.xml
@@ -188,6 +188,55 @@ android:text="@string/dashboard_state_ipaddress_off"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/graph"
/>
+
+ <View
+ android:id="@+id/graph_legend_blocked_icon"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/graph_legend"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="16dp"
+ android:background="@drawable/ic_legend_blocked"
+ />
+ <TextView
+ android:id="@+id/graph_legend_blocked"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_blocked_icon"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_blocked_icon"
+ android:layout_marginTop="8dp"
+ android:text="@string/graph_legend_blocked"
+ />
+
+ <View
+ android:id="@+id/graph_legend_allowed_icon"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_blocked"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_blocked_icon"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="32dp"
+ android:background="@drawable/ic_legend_leaked"
+ />
+ <TextView
+ android:id="@+id/graph_legend_allowed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_allowed_icon"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_blocked_icon"
+ android:layout_marginTop="8dp"
+ android:text="@string/graph_legend_allowed"
+ />
+
<TextView
android:id="@+id/graph_empty"
android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/trackers_item_graph.xml b/app/src/main/res/layout/trackers_item_graph.xml
index 5cc2d98..933b96c 100644
--- a/app/src/main/res/layout/trackers_item_graph.xml
+++ b/app/src/main/res/layout/trackers_item_graph.xml
@@ -55,6 +55,55 @@
android:layout_width="match_parent"
app:layout_constraintTop_toBottomOf="@+id/graph_period_label"
/>
+
+ <View
+ android:id="@+id/graph_legend_blocked_icon"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/graph"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="16dp"
+ android:background="@drawable/ic_legend_blocked"
+ />
+ <TextView
+ android:id="@+id/graph_legend_blocked"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_blocked_icon"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_blocked_icon"
+ android:layout_marginTop="8dp"
+ android:text="@string/graph_legend_blocked"
+ />
+
+ <View
+ android:id="@+id/graph_legend_allowed_icon"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_blocked"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_blocked_icon"
+ android:layout_marginTop="8dp"
+ android:layout_marginStart="32dp"
+ android:background="@drawable/ic_legend_leaked"
+ />
+ <TextView
+ android:id="@+id/graph_legend_allowed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ app:layout_constraintLeft_toRightOf="@+id/graph_legend_allowed_icon"
+ app:layout_constraintBottom_toBottomOf="@+id/graph_legend_blocked_icon"
+ android:layout_marginTop="8dp"
+ android:text="@string/graph_legend_allowed"
+ />
+
<TextView
android:id="@+id/graph_empty"
android:layout_width="match_parent"
diff --git a/app/src/main/res/layout/widget.xml b/app/src/main/res/layout/widget.xml
index dc3ac16..ae5bfe7 100644
--- a/app/src/main/res/layout/widget.xml
+++ b/app/src/main/res/layout/widget.xml
@@ -178,205 +178,471 @@
android:layout_marginHorizontal="24dp"
android:layout_height="26dp"
>
- <ImageView
- android:id="@+id/widget_graph_bar_0"
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_1"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_2"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_3"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_2"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_2"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_4"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_3"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_3"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_5"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_4"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_4"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_6"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_5"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_5"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_7"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_6"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_6"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_8"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_7"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_7"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_9"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_8"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_8"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_10"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_9"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_9"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_11"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_10"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_10"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_12"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_11"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_11"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_13"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_12"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_12"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_14"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_13"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_13"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_15"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_14"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_14"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_16"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_15"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_15"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_17"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_16"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_16"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_18"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_17"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_17"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_19"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_18"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_18"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_20"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_19"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_19"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_21"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_20"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_20"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_22"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_21"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_21"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
android:layout_marginRight="1.5dp"
- />
- <ImageView
- android:id="@+id/widget_graph_bar_23"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_22"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_22"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
+ <FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
- android:src="@color/accent"
- />
- </LinearLayout>
+ android:layout_marginRight="1.5dp"
+ >
+ <ImageView
+ android:id="@+id/widget_leaked_graph_bar_23"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/red_off"
+ />
+ <ImageView
+ android:id="@+id/widget_graph_bar_23"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@color/accent"
+ />
+ </FrameLayout>
-<!-- <com.github.mikephil.charting.charts.BarChart-->
-<!-- android:id="@+id/graph"-->
-<!-- android:layout_height="144dp"-->
-<!-- android:layout_width="match_parent"-->
-<!-- android:layout_marginHorizontal="24dp"-->
-<!-- />-->
+ </LinearLayout>
<TextView
android:id="@+id/graph_legend"
@@ -387,9 +653,57 @@
android:textColor="@color/on_primary_high_emphasis"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="24dp"
- android:layout_marginBottom="24dp"
/>
+ <LinearLayout
+ android:id="@+id/graph_legend_values"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginTop="16dp"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginBottom="24dp"
+ >
+
+ <ImageView
+ android:id="@+id/graph_legend_blocked_icon"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ android:src="@drawable/ic_legend_blocked"
+ />
+ <TextView
+ android:id="@+id/graph_legend_blocked"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:textColor="@color/on_primary_medium_emphasis"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ android:text="@string/graph_legend_blocked"
+ />
+
+ <ImageView
+ android:id="@+id/graph_legend_allowed_icon"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:padding="1dp"
+ android:layout_marginStart="32dp"
+ android:src="@drawable/ic_legend_leaked"
+ />
+
+ <TextView
+ android:id="@+id/graph_legend_allowed"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:text="0 Trackers"
+ android:textColor="@color/on_primary_medium_emphasis"
+ android:layout_marginStart="8dp"
+ android:textSize="12sp"
+ android:text="@string/graph_legend_allowed"
+ />
+ </LinearLayout>
+
<TextView
android:id="@+id/graph_empty"
android:layout_width="match_parent"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ce7709c..88bd473 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4,6 +4,8 @@
<!-- Commons -->
<string name="dummy_system_app_label">System</string>
<string name="graph_empty_message">Congratulations! No trackers are profiling you.</string>
+ <string name="graph_legend_blocked">Blocked leaks</string>
+ <string name="graph_legend_allowed">Allowed leaks</string>
<!-- Dashboard -->
<string name="dashboard_title">@string/app_name</string>
diff --git a/build.gradle b/build.gradle
index 5ff250d..c7815e7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,10 +8,10 @@ buildscript {
'minSdk' : 26,
'targetSdk' : 29,
'version' : [
- 'major': 0,
- 'minor': 6,
+ 'major': 1,
+ 'minor': 0,
'patch': 0,
- 'build': "milestone-3",
+ 'build': "milestone-5",
],
]