summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.idea/codeStyles/Project.xml1
-rw-r--r--.idea/misc.xml10
-rw-r--r--.idea/runConfigurations.xml10
-rw-r--r--app/build.gradle24
-rw-r--r--app/src/main/AndroidManifest.xml3
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt (renamed from app/src/main/java/foundation/e/privacycentralapp/MainActivity.kt)10
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/common/RightRadioButton.kt43
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt227
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/dummy/Extensions.kt32
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt205
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt199
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt40
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt53
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFeature.kt110
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt116
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyViewModel.kt40
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFeature.kt152
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationFragment.kt178
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeLocationViewModel.kt40
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt60
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsFragment.kt105
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt63
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFeature.kt118
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt79
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsViewModel.kt40
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt62
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/main/MainViewModel.kt22
-rw-r--r--app/src/main/res/drawable/dummy_img_map_picker.pngbin0 -> 339121 bytes
-rw-r--r--app/src/main/res/drawable/dummy_leakage_analytics.pngbin0 -> 25328 bytes
-rw-r--r--app/src/main/res/drawable/ic_apps_permissions.xml22
-rw-r--r--app/src/main/res/drawable/ic_body_monitor.xml19
-rw-r--r--app/src/main/res/drawable/ic_calendar.xml10
-rw-r--r--app/src/main/res/drawable/ic_call.xml10
-rw-r--r--app/src/main/res/drawable/ic_chevron_right_24dp.xml27
-rw-r--r--app/src/main/res/drawable/ic_facebook.xml31
-rw-r--r--app/src/main/res/drawable/ic_internet_activity.xml22
-rw-r--r--app/src/main/res/drawable/ic_location.xml10
-rw-r--r--app/src/main/res/drawable/ic_my_location.xml22
-rw-r--r--app/src/main/res/drawable/ic_privacy_toggle.xml22
-rw-r--r--app/src/main/res/drawable/ic_tracked.xml22
-rw-r--r--app/src/main/res/layout/activity_main.xml18
-rw-r--r--app/src/main/res/layout/fragment_dashboard.xml350
-rw-r--r--app/src/main/res/layout/fragment_fake_location.xml152
-rw-r--r--app/src/main/res/layout/fragment_internet_activity_policy.xml105
-rw-r--r--app/src/main/res/layout/fragment_permission_apps.xml46
-rw-r--r--app/src/main/res/layout/fragment_permissions.xml57
-rw-r--r--app/src/main/res/layout/fragment_quick_protection.xml68
-rw-r--r--app/src/main/res/layout/item_permission.xml73
-rw-r--r--app/src/main/res/layout/item_permission_apps.xml44
-rw-r--r--app/src/main/res/values-night/themes.xml16
-rw-r--r--app/src/main/res/values/strings.xml35
-rw-r--r--app/src/main/res/values/themes.xml14
-rw-r--r--build.gradle27
-rw-r--r--dependencies.gradle4
-rw-r--r--flow-mvi/.gitignore1
-rw-r--r--flow-mvi/build.gradle31
-rw-r--r--flow-mvi/src/main/java/foundation/e/flowmvi/MVIView.kt27
-rw-r--r--flow-mvi/src/main/java/foundation/e/flowmvi/Store.kt24
-rw-r--r--flow-mvi/src/main/java/foundation/e/flowmvi/Types.kt42
-rw-r--r--flow-mvi/src/main/java/foundation/e/flowmvi/feature/BaseFeature.kt144
-rw-r--r--flow-mvi/src/main/java/foundation/e/flowmvi/feature/Feature.kt62
-rw-r--r--gradle/dependencyGraph.gradle140
-rw-r--r--settings.gradle1
64 files changed, 3674 insertions, 67 deletions
diff --git a/.gitignore b/.gitignore
index e1e9a78..7aa06c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ local.properties
.idea/compiler.xml
/.idea/assetWizardSettings.xml
/.idea/jarRepositories.xml
+/.idea/google-java-format.xml
gradle.xml
markdown-*.xml
*.iml
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index b66e2e7..c274a62 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -158,6 +158,7 @@
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+ <option name="RIGHT_MARGIN" value="100" />
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
diff --git a/.idea/misc.xml b/.idea/misc.xml
index af6eff4..2f6c31d 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,7 +5,7 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
- <list size="12">
+ <list size="15">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
@@ -18,12 +18,15 @@
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
<item index="10" class="java.lang.String" itemvalue="android.annotation.Nullable" />
<item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
+ <item index="12" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.Nullable" />
+ <item index="13" class="java.lang.String" itemvalue="io.reactivex.annotations.Nullable" />
+ <item index="14" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
- <list size="11">
+ <list size="14">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
@@ -35,6 +38,9 @@
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
<item index="9" class="java.lang.String" itemvalue="android.annotation.NonNull" />
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
+ <item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
+ <item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
+ <item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
</list>
</value>
</option>
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..797acea
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="RunConfigurationProducerService">
+ <option name="ignoredProducers">
+ <set>
+ <option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
+ </set>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 35e1c73..15fa88c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,14 +4,14 @@ plugins {
}
android {
- compileSdkVersion 29
+ compileSdkVersion buildConfig.compileSdk
defaultConfig {
applicationId "foundation.e.privacycentralapp"
- minSdkVersion 24
- targetSdkVersion 29
- versionCode 1
- versionName "1.0"
+ minSdkVersion buildConfig.minSdk
+ targetSdkVersion buildConfig.targetSdk
+ versionCode buildConfig.version.code
+ versionName buildConfig.version.fullName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -26,17 +26,19 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
- kotlinOptions {
- jvmTarget = '1.8'
- }
}
dependencies {
- implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.32"
- implementation 'androidx.core:core-ktx:1.3.2'
+ implementation project(":flow-mvi")
+ implementation Libs.Kotlin.stdlib
+ implementation Libs.AndroidX.coreKtx
+ implementation Libs.AndroidX.Fragment.fragmentKtx
implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation Libs.AndroidX.Lifecycle.runtime
+ implementation Libs.AndroidX.Lifecycle.viewmodel
+
implementation 'com.google.android.material:material:1.3.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a28e77e..2c3b055 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,13 +3,14 @@
package="foundation.e.privacycentralapp">
<application
+ android:name=".PrivacyCentralApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PrivacyCentralApp">
- <activity android:name=".MainActivity">
+ <activity android:name=".main.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/app/src/main/java/foundation/e/privacycentralapp/MainActivity.kt b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
index 3dd2145..87be346 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/MainActivity.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/PrivacyCentralApplication.kt
@@ -17,12 +17,6 @@
package foundation.e.privacycentralapp
-import android.os.Bundle
-import androidx.appcompat.app.AppCompatActivity
+import android.app.Application
-class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- }
-}
+class PrivacyCentralApplication : Application()
diff --git a/app/src/main/java/foundation/e/privacycentralapp/common/RightRadioButton.kt b/app/src/main/java/foundation/e/privacycentralapp/common/RightRadioButton.kt
new file mode 100644
index 0000000..bbc108b
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/common/RightRadioButton.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.common
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.RadioButton
+
+/**
+ * A custom [RadioButton] which displays the radio drawable on the right side.
+ */
+@SuppressLint("AppCompatCustomView")
+class RightRadioButton : RadioButton {
+
+ constructor(context: Context) : super(context)
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
+ context,
+ attrs,
+ defStyleAttr
+ )
+
+ // Returns layout direction as right-to-left to draw the compound button on right side.
+ override fun getLayoutDirection(): Int {
+ return LAYOUT_DIRECTION_RTL
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt b/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt
new file mode 100644
index 0000000..aef994b
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt
@@ -0,0 +1,227 @@
+/*
+ * 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 kotlin.random.Random
+
+// ======================================================//
+//
+// ================ ==== ==== ===============
+// ================ ====== ====== ================
+// ==== ======== ======== ==== ====
+// ==== ========= ========= ==== ====
+// ==== ==================== ================
+// ==== ==== ======== ==== ===============
+// ==== ==== ==== ==== ====
+// ================ ==== == ==== ====
+// ================ ==== ==== ====
+//
+// ======================================================//
+
+/**
+ * This whole file acts as a dummy source. All data classes and method implementations
+ * are not proper ones and are subject to change anytime.
+ */
+
+/**
+ * Dummmy permission data class.
+ */
+data class Permission(
+ val id: Int,
+ val name: String,
+ val iconId: Int,
+ val packagesRequested: Set<String> = emptySet(),
+ val packagesAllowed: Set<String> = emptySet()
+)
+
+enum class LocationMode {
+ REAL_LOCATION, RANDOM_LOCATION, CUSTOM_LOCATION
+}
+
+enum class InternetPrivacyMode {
+ REAL_IP, HIDE_IP
+}
+
+data class Location(val mode: LocationMode, val latitude: Double, val longitude: Double)
+
+object DummyDataSource {
+
+ const val trackersCount = 77
+ private val _activeTrackersCount = MutableStateFlow(10)
+ val activeTrackersCount = _activeTrackersCount.asStateFlow()
+
+ private val _location = MutableStateFlow(Location(LocationMode.REAL_LOCATION, 0.0, 0.0))
+ val location = _location.asStateFlow()
+
+ private val _internetActivityMode = MutableStateFlow(InternetPrivacyMode.REAL_IP)
+ val internetActivityMode = _internetActivityMode.asStateFlow()
+
+ /**
+ * Declare dummy permissions with following ids
+ *
+ * [0] -> Body sensor
+ * [1] -> Calendar
+ * [2] -> Call Logs
+ * [3] -> Location
+ */
+ val permissions = arrayOf("Body Sensor", "Calendar", "Call Logs", "Location")
+
+ private val permissionIcons = arrayOf(
+ R.drawable.ic_body_monitor,
+ R.drawable.ic_calendar,
+ R.drawable.ic_call,
+ R.drawable.ic_location
+ )
+
+ val packages = arrayOf(
+ "facebook",
+ "uber",
+ "instagram",
+ "openstreetmap",
+ "truecaller",
+ "netflix",
+ "firefox",
+ "pubg",
+ "amazon",
+ "calendar",
+ "zohomail",
+ "privacycentral"
+ )
+
+ val _populatedPermissions = MutableStateFlow(fetchPermissions())
+ val populatedPermission = _populatedPermissions.asStateFlow()
+
+ private val _appsUsingLocationPerm =
+ MutableStateFlow(_populatedPermissions.value[3].packagesAllowed)
+ val appsUsingLocationPerm = _appsUsingLocationPerm.asStateFlow()
+
+ private fun fetchPermissions(): List<Permission> {
+ val result = mutableListOf<Permission>()
+ permissions.forEachIndexed { index, permission ->
+ when (index) {
+ 0 -> result.add(Permission(index, permission, permissionIcons[index]))
+ 1 -> {
+ val randomPackages = getRandomItems(packages, 8)
+ val grantedPackages = getRandomItems(randomPackages, 3)
+ result.add(
+ Permission(
+ index,
+ permission,
+ permissionIcons[index],
+ randomPackages,
+ grantedPackages
+ )
+ )
+ }
+ 2 -> {
+ val randomPackages = getRandomItems(packages, 10)
+ val grantedPackages = getRandomItems(randomPackages, 9)
+ result.add(
+ Permission(
+ index,
+ permission,
+ permissionIcons[index],
+ randomPackages,
+ grantedPackages
+ )
+ )
+ }
+ 3 -> {
+ val randomPackages = getRandomItems(packages, 5)
+ val grantedPackages = getRandomItems(randomPackages, 3)
+ result.add(
+ Permission(
+ index,
+ permission,
+ permissionIcons[index],
+ randomPackages,
+ grantedPackages
+ )
+ )
+ }
+ }
+ }
+ return result
+ }
+
+ private fun <T> getRandomItems(data: Array<T>, limit: Int): Set<T> =
+ getRandomItems(data.toSet(), limit)
+
+ private fun <T> getRandomItems(data: Set<T>, limit: Int): Set<T> {
+ val randomItems = mutableSetOf<T>()
+ val localData = data.toMutableList()
+ repeat(limit) {
+ val generated = localData.random()
+ randomItems.add(generated)
+ localData.remove(generated)
+ }
+ return randomItems
+ }
+
+ fun getPermission(permissionId: Int): Permission = populatedPermission.value[permissionId]