summaryrefslogtreecommitdiff
path: root/app/src/main/java/foundation/e/privacycentralapp
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/foundation/e/privacycentralapp')
-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.kt141
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardActivity.kt49
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFeature.kt38
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt95
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt16
-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/InternetPrivacyFragment.kt38
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/location/FakeMyLocationFragment.kt38
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt52
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionControlFragment.kt59
-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/PermissionsFragment.kt60
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt65
-rw-r--r--app/src/main/java/foundation/e/privacycentralapp/main/MainViewModel.kt22
15 files changed, 764 insertions, 68 deletions
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..65d072a
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/dummy/DummyDataSource.kt
@@ -0,0 +1,141 @@
+/*
+ * 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
+
+// ======================================================//
+//
+// ============ ==== ==== ============
+// ============ ===== ===== ==== ====
+// ==== ====== ====== ==== ====
+// ==== ======= ======= ============
+// ==== ================ ====
+// ==== ==== ====== ==== ====
+// ============ ==== ==== ==== ====
+// ============ ==== == ==== ====
+//
+// ======================================================//
+
+/**
+ * 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 name: String,
+ val iconId: Int,
+ val packagesRequested: List<String> = emptyList(),
+ val packagesAllowed: List<String> = emptyList()
+)
+
+object DummyDataSource {
+ val permissions = arrayOf("Body Sensor", "Calendar", "Call Logs", "Location")
+ val icons = 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 populatedPermission: List<Permission> by lazy {
+ fetchPermissions()
+ }
+
+ private fun fetchPermissions(): List<Permission> {
+ val result = mutableListOf<Permission>()
+ permissions.forEachIndexed { index, permission ->
+ when (index) {
+ 0 -> result.add(Permission(permission, icons[index]))
+ 1 -> {
+ val randomPackages = getRandomItems(packages, 8)
+ val grantedPackages = getRandomItems(randomPackages, 3)
+ result.add(
+ Permission(
+ permission,
+ icons[index],
+ randomPackages,
+ grantedPackages
+ )
+ )
+ }
+ 2 -> {
+ val randomPackages = getRandomItems(packages, 10)
+ val grantedPackages = getRandomItems(randomPackages, 9)
+ result.add(
+ Permission(
+ permission,
+ icons[index],
+ randomPackages,
+ grantedPackages
+ )
+ )
+ }
+ 3 -> {
+ val randomPackages = getRandomItems(packages, 5)
+ val grantedPackages = getRandomItems(randomPackages, 3)
+ result.add(
+ Permission(
+ permission,
+ icons[index],
+ randomPackages,
+ grantedPackages
+ )
+ )
+ }
+ }
+ }
+ return result
+ }
+
+ private fun <T> getRandomItems(data: Array<T>, limit: Int): List<T> =
+ getRandomItems(data.asList(), limit)
+
+ private fun <T> getRandomItems(data: List<T>, limit: Int): List<T> {
+ val randomItems = mutableSetOf<T>()
+ val localData = data.toMutableList()
+ repeat(limit) {
+ val generated = localData.random()
+ randomItems.add(generated)
+ localData.remove(generated)
+ }
+ return randomItems.toList()
+ }
+
+ fun getPermission(permissionId: Int): Permission {
+ return populatedPermission.get(permissionId)
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardActivity.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardActivity.kt
deleted file mode 100644
index ef296ce..0000000
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardActivity.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2021 E FOUNDATION
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package foundation.e.privacycentralapp.features.dashboard
-
-import android.graphics.Color
-import android.os.Bundle
-import android.text.Spannable
-import android.text.SpannableString
-import android.text.style.ForegroundColorSpan
-import android.widget.TextView
-import androidx.appcompat.app.AppCompatActivity
-import foundation.e.privacycentralapp.R
-
-class DashboardActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- title = "My Privacy Dashboard"
- setSupportActionBar(findViewById(R.id.toolbar))
-
- addClickToMore(findViewById<TextView>(R.id.personal_leakag_info))
- }
-
- private fun addClickToMore(textView: TextView) {
- val clickToMore = SpannableString("Click to learn more")
- clickToMore.setSpan(
- ForegroundColorSpan(Color.parseColor("#007fff")),
- 0,
- clickToMore.length,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- )
- textView.append(clickToMore)
- }
-}
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 9b8e28f..ecadea1 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
@@ -23,47 +23,51 @@ import foundation.e.flowmvi.feature.BaseFeature
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.flowOf
-// Define a state machine for HomeFeature
-object HomeFeature {
+// Define a state machine for Dashboard Feature
+object DashboardFeature {
sealed class State {
- object Loading : State()
- object Loaded : State()
+ object DashboardState : State()
+ object QuickProtectionState : State()
}
sealed class SingleEvent {
- object NavigateToQuickProtection : SingleEvent()
- object NavigateToTrackers : SingleEvent()
- object NavigateToInternetActivityPolicy : SingleEvent()
- object NavigateToLocation : SingleEvent()
- object NavigateToPermissionManagement : SingleEvent()
+ object NavigateToQuickProtectionSingleEvent : SingleEvent()
+ object NavigateToTrackersSingleEvent : SingleEvent()
+ object NavigateToInternetActivityPolicySingleEvent : SingleEvent()
+ object NavigateToLocationSingleEvent : SingleEvent()
+ object NavigateToPermissionManagementSingleEvent : SingleEvent()
}
sealed class Action {
- object load : Action()
+ object ShowQuickPrivacyProtectionInfoAction : Action()
+ object ShowDashboardAction : Action()
}
sealed class Effect {
- object LoadingFinished : Effect()
+ object OpenQuickPrivacyProtectionEffect : Effect()
+ object OpenDashboardEffect : Effect()
}
}
-private val reducer: Reducer<HomeFeature.State, HomeFeature.Effect> = { _, effect ->
+private val reducer: Reducer<DashboardFeature.State, DashboardFeature.Effect> = { _, effect ->
when (effect) {
- HomeFeature.Effect.LoadingFinished -> HomeFeature.State.Loaded
+ DashboardFeature.Effect.OpenQuickPrivacyProtectionEffect -> DashboardFeature.State.QuickProtectionState
+ DashboardFeature.Effect.OpenDashboardEffect -> DashboardFeature.State.DashboardState
}
}
-private val actor: Actor<HomeFeature.State, HomeFeature.Action, HomeFeature.Effect> =
+private val actor: Actor<DashboardFeature.State, DashboardFeature.Action, DashboardFeature.Effect> =
{ _, action ->
when (action) {
- HomeFeature.Action.load -> flowOf(HomeFeature.Effect.LoadingFinished)
+ DashboardFeature.Action.ShowQuickPrivacyProtectionInfoAction -> flowOf(DashboardFeature.Effect.OpenQuickPrivacyProtectionEffect)
+ DashboardFeature.Action.ShowDashboardAction -> flowOf(DashboardFeature.Effect.OpenDashboardEffect)
}
}
fun homeFeature(
- initialState: HomeFeature.State = HomeFeature.State.Loading,
+ initialState: DashboardFeature.State = DashboardFeature.State.DashboardState,
coroutineScope: CoroutineScope
-) = BaseFeature<HomeFeature.State, HomeFeature.Action, HomeFeature.Effect, HomeFeature.SingleEvent>(
+) = BaseFeature<DashboardFeature.State, DashboardFeature.Action, DashboardFeature.Effect, DashboardFeature.SingleEvent>(
initialState,
actor,
reducer,
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
new file mode 100644
index 0000000..d6a91b8
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardFragment.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.dashboard
+
+import android.graphics.Color
+import android.os.Bundle
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.style.ForegroundColorSpan
+import android.view.View
+import android.widget.TextView
+import android.widget.Toolbar
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.fragment.app.add
+import androidx.fragment.app.commit
+import androidx.lifecycle.lifecycleScope
+import foundation.e.flowmvi.MVIView
+import foundation.e.privacycentralapp.R
+import kotlinx.coroutines.flow.Flow
+
+class DashboardFragment :
+ Fragment(R.layout.fragment_dashboard),
+ MVIView<DashboardFeature.State, DashboardFeature.Action> {
+
+ private val viewModel: DashboardViewModel by activityViewModels()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ lifecycleScope.launchWhenStarted {
+ viewModel.homeFeature.takeView(this, this@DashboardFragment)
+ }
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
+ setupToolbar(toolbar)
+ addClickToMore(view.findViewById(R.id.personal_leakag_info))
+ view.let {
+ it.findViewById<TextView>(R.id.tap_to_enable_quick_protection).setOnClickListener {
+ viewModel.submitAction(DashboardFeature.Action.ShowQuickPrivacyProtectionInfoAction)
+ }
+ }
+ }
+
+ private fun setupToolbar(toolbar: Toolbar) {
+ val activity = requireActivity()
+ activity.setActionBar(toolbar)
+ activity.title = "My Privacy Dashboard"
+ }
+
+ private fun addClickToMore(textView: TextView) {
+ val clickToMore = SpannableString("Click to learn more")
+ clickToMore.setSpan(
+ ForegroundColorSpan(Color.parseColor("#007fff")),
+ 0,
+ clickToMore.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ textView.append(clickToMore)
+ }
+
+ override fun render(state: DashboardFeature.State) {
+ when (state) {
+ is DashboardFeature.State.QuickProtectionState -> {
+ requireActivity().supportFragmentManager.commit {
+ add<QuickProtectionFragment>(R.id.container)
+ setReorderingAllowed(true)
+ addToBackStack("dashboard")
+ }
+ }
+ else -> {
+ // TODO: any remaining state must either be handled or needs to be passed down to the UI.
+ }
+ }
+ }
+
+ override fun actions(): Flow<DashboardFeature.Action> = viewModel.actions
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
index 82c6c11..12696d5 100644
--- a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/DashboardViewModel.kt
@@ -20,11 +20,23 @@ package foundation.e.privacycentralapp.features.dashboard
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import foundation.e.flowmvi.feature.BaseFeature
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.launch
class DashboardViewModel : ViewModel() {
- val homeFeature: BaseFeature<HomeFeature.State, HomeFeature.Action,
- HomeFeature.Effect, HomeFeature.SingleEvent> by lazy {
+ private val _actions = MutableSharedFlow<DashboardFeature.Action>()
+ val actions = _actions.asSharedFlow()
+
+ val homeFeature: BaseFeature<DashboardFeature.State, DashboardFeature.Action,
+ DashboardFeature.Effect, DashboardFeature.SingleEvent> by lazy {
homeFeature(coroutineScope = viewModelScope)
}
+
+ fun submitAction(action: DashboardFeature.Action) {
+ viewModelScope.launch {
+ _actions.emit(action)
+ }
+ }
}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt
new file mode 100644
index 0000000..c120b49
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/dashboard/QuickProtectionFragment.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.dashboard
+
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import android.widget.Toolbar
+import androidx.activity.addCallback
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import foundation.e.privacycentralapp.R
+
+class QuickProtectionFragment : Fragment(R.layout.fragment_quick_protection) {
+
+ private val viewModel: DashboardViewModel by activityViewModels()
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
+ setupToolbar(toolbar)
+ }
+
+ override fun onAttach(context: Context) {
+ super.onAttach(context)
+ requireActivity().onBackPressedDispatcher.addCallback(this, true) {
+ viewModel.submitAction(DashboardFeature.Action.ShowDashboardAction)
+ this.isEnabled = false
+ requireActivity().onBackPressed()
+ }
+ }
+
+ private fun setupToolbar(toolbar: Toolbar) {
+ val activity = requireActivity()
+ activity.setActionBar(toolbar)
+ activity.title = "Quick protection"
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
new file mode 100644
index 0000000..ddba807
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/internetprivacy/InternetPrivacyFragment.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.internetprivacy
+
+import android.os.Bundle
+import android.view.View
+import android.widget.Toolbar
+import androidx.fragment.app.Fragment
+import foundation.e.privacycentralapp.R
+
+class InternetPrivacyFragment : Fragment(R.layout.fragment_internet_activity_policy) {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
+ setupToolbar(toolbar)
+ }
+
+ private fun setupToolbar(toolbar: Toolbar) {
+ val activity = requireActivity()
+ activity.setActionBar(toolbar)
+ activity.title = "My Internet Activity Privacy"
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeMyLocationFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeMyLocationFragment.kt
new file mode 100644
index 0000000..24d3951
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/location/FakeMyLocationFragment.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.location
+
+import android.os.Bundle
+import android.view.View
+import android.widget.Toolbar
+import androidx.fragment.app.Fragment
+import foundation.e.privacycentralapp.R
+
+class FakeMyLocationFragment : Fragment(R.layout.fragment_fake_location) {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
+ setupToolbar(toolbar)
+ }
+
+ private fun setupToolbar(toolbar: Toolbar) {
+ val activity = requireActivity()
+ activity.setActionBar(toolbar)
+ activity.title = "Fake My Location"
+ }
+}
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
new file mode 100644
index 0000000..19460cc
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionAppsAdapter.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.permissions
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.Switch
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+
+class PermissionAppsAdapter(private val dataSet: List<Pair<String, Boolean>>) :
+ RecyclerView.Adapter<PermissionAppsAdapter.PermissionViewHolder>() {
+
+ class PermissionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val appName: TextView = view.findViewById(R.id.app_title)
+ @SuppressLint("UseSwitchCompatOrMaterialCode") val togglePermission: Switch = view.findViewById(R.id.togglePermission)
+ val appIcon: ImageView = view.findViewById(R.id.app_icon)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PermissionViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_permission_apps, parent, false)
+ return PermissionViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: PermissionViewHolder, position: Int) {
+ val permission = dataSet[position]
+ holder.appName.text = permission.first
+ holder.togglePermission.isChecked = permission.second
+ }
+
+ override fun getItemCount(): Int = dataSet.size
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionControlFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionControlFragment.kt
new file mode 100644
index 0000000..55e3f88
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionControlFragment.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.permissions
+
+import android.os.Bundle
+import android.view.View
+import android.widget.TextView
+import android.widget.Toolbar
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.dummy.DummyDataSource
+
+class PermissionControlFragment : Fragment(R.layout.fragment_permission_control) {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
+ setupToolbar(toolbar)
+
+ val permissionId = requireArguments().getInt("PERMISSION_ID")
+ loadData(view, permissionId)
+ }
+
+ private fun loadData(view: View, permissionId: Int) {
+ val recyclerView = view.findViewById<RecyclerView>(R.id.recylcer_view_permission_apps)
+ val permission = DummyDataSource.getPermission(permissionId)
+ val listOfPackages = mutableListOf<Pair<String, Boolean>>()
+ permission.packagesRequested.forEach {
+ listOfPackages.add(it to permission.packagesAllowed.contains(it))
+ }
+ recyclerView.layoutManager = LinearLayoutManager(requireContext())
+ recyclerView.setHasFixedSize(true)
+ recyclerView.adapter = PermissionAppsAdapter(listOfPackages)
+ view.findViewById<TextView>(R.id.permission_control).text =
+ getString(R.string.apps_access_to_permission, permission.name)
+ }
+
+ private fun setupToolbar(toolbar: Toolbar) {
+ val activity = requireActivity()
+ activity.setActionBar(toolbar)
+ activity.title = "My Apps Permission"
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt
new file mode 100644
index 0000000..330a1ac
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsAdapter.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.permissions
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.dummy.Permission
+
+class PermissionsAdapter(
+ private val context: Context,
+ private val dataSet: List<Permission>,
+ private val listener: (Int) -> Unit
+) :
+ RecyclerView.Adapter<PermissionsAdapter.PermissionViewHolder>() {
+
+ class PermissionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ val nameView: TextView = view.findViewById(R.id.permission_title)
+ val permissionCountView: TextView = view.findViewById(R.id.permission_count)
+ val permissionIcon: ImageView = view.findViewById(R.id.permission_icon)
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PermissionViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_permission, parent, false)
+ val holder = PermissionViewHolder(view)
+ view.setOnClickListener { listener(holder.adapterPosition) }
+ return holder
+ }
+
+ override fun onBindViewHolder(holder: PermissionViewHolder, position: Int) {
+ val permission = dataSet[position]
+ holder.nameView.text = permission.name
+ holder.permissionCountView.text = context.getString(
+ R.string.apps_allowed,
+ permission.packagesAllowed.size,
+ permission.packagesRequested.size
+ )
+ holder.permissionIcon.setImageResource(permission.iconId)
+ }
+
+ override fun getItemCount(): Int = dataSet.size
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt
new file mode 100644
index 0000000..27247ea
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/features/permissions/PermissionsFragment.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.permissions
+
+import android.os.Bundle
+import android.view.View
+import android.widget.Toolbar
+import androidx.core.os.bundleOf
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.add
+import androidx.fragment.app.commit
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.dummy.DummyDataSource
+
+class PermissionsFragment : Fragment(R.layout.fragment_permissions) {
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
+ setupToolbar(toolbar)
+
+ loadDataIntoRecyclerView(view.findViewById(R.id.recylcer_view_permissions))
+ }
+
+ private fun loadDataIntoRecyclerView(view: RecyclerView) {
+ val permissions = DummyDataSource.populatedPermission
+ view.layoutManager = LinearLayoutManager(requireContext())
+ view.setHasFixedSize(true)
+ view.adapter = PermissionsAdapter(requireContext(), permissions) { permissionId ->
+ requireActivity().supportFragmentManager.commit {
+ val bundle = bundleOf("PERMISSION_ID" to permissionId)
+ add<PermissionControlFragment>(R.id.container, args = bundle)
+ setReorderingAllowed(true)
+ addToBackStack("permissions")
+ }
+ }
+ }
+
+ private fun setupToolbar(toolbar: Toolbar) {
+ val activity = requireActivity()
+ activity.setActionBar(toolbar)
+ activity.title = "My Apps Permission"
+ }
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt b/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
new file mode 100644
index 0000000..d5b449f
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/main/MainActivity.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.main
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.viewModels
+import androidx.fragment.app.FragmentActivity
+import androidx.fragment.app.add
+import androidx.fragment.app.commit
+import foundation.e.privacycentralapp.R
+import foundation.e.privacycentralapp.features.permissions.PermissionsFragment
+
+open class MainActivity : FragmentActivity(R.layout.activity_main) {
+
+ private val viewModel: MainViewModel by viewModels()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ if (savedInstanceState == null) {
+ supportFragmentManager.commit {
+ setReorderingAllowed(true)
+ add<PermissionsFragment>(R.id.container)
+ }
+ }
+ }
+
+ override fun onPostCreate(savedInstanceState: Bundle?) {
+ super.onPostCreate(savedInstanceState)
+ handleIntent(intent)
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ handleIntent(intent)
+ }
+
+ open fun handleIntent(intent: Intent) {}
+
+ override fun finishAfterTransition() {
+ val resultData = Intent()
+ val result = onPopulateResultIntent(resultData)
+ setResult(result, resultData)
+
+ super.finishAfterTransition()
+ }
+
+ open fun onPopulateResultIntent(intent: Intent): Int = Activity.RESULT_OK
+}
diff --git a/app/src/main/java/foundation/e/privacycentralapp/main/MainViewModel.kt b/app/src/main/java/foundation/e/privacycentralapp/main/MainViewModel.kt
new file mode 100644
index 0000000..7e758b7
--- /dev/null
+++ b/app/src/main/java/foundation/e/privacycentralapp/main/MainViewModel.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.main
+
+import androidx.lifecycle.ViewModel
+
+class MainViewModel : ViewModel()