diff --git a/app/build.gradle b/app/build.gradle
index a9d0a0829..c26b5d173 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -247,8 +247,8 @@ dependencies {
fullImplementation 'com.github.kirich1409:viewbindingpropertydelegate-noreflection:1.5.9'
// from: https://jitpack.io/#celzero/firestack
- download 'com.github.celzero:firestack:f5a2218ed6@aar'
- implementation 'com.github.celzero:firestack:f5a2218ed6@aar'
+ download 'com.github.celzero:firestack:a94a7e78a6@aar'
+ implementation 'com.github.celzero:firestack:a94a7e78a6@aar'
// Work manager
implementation('androidx.work:work-runtime-ktx:2.9.0') {
@@ -275,7 +275,8 @@ dependencies {
fullImplementation 'androidx.biometric:biometric:1.1.0'
- playImplementation 'com.google.android.play:core:1.10.3' // for new version updater
+ playImplementation 'com.google.android.play:app-update:2.1.0'
+ playImplementation 'com.google.android.play:app-update-ktx:2.1.0'
// for encrypting wireguard configuration files
implementation("androidx.security:security-crypto:1.1.0-alpha06")
diff --git a/app/src/full/AndroidManifest.xml b/app/src/full/AndroidManifest.xml
index a9de24e02..d5cb6e6bb 100644
--- a/app/src/full/AndroidManifest.xml
+++ b/app/src/full/AndroidManifest.xml
@@ -3,8 +3,9 @@
xmlns:tools="http://schemas.android.com/tools">
-
+
-
+
+ android:finishOnTaskLaunch="true" />
+ android:exported="true"
+ android:label="@string/app_name"
+ android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
@@ -136,6 +141,7 @@
(
+ DIFF_CALLBACK
+ ),
+ AppDomainRulesBottomSheet.OnBottomSheetDialogFragmentDismiss {
+
+ companion object {
+ private val DIFF_CALLBACK =
+ object : DiffUtil.ItemCallback() {
+
+ override fun areItemsTheSame(
+ oldConnection: AppConnection,
+ newConnection: AppConnection
+ ) = oldConnection == newConnection
+
+ override fun areContentsTheSame(
+ oldConnection: AppConnection,
+ newConnection: AppConnection
+ ) = oldConnection == newConnection
+ }
+ }
+
+ private lateinit var adapter: AppWiseDomainsAdapter
+
+ // ui component to update/toggle the buttons
+ data class ToggleBtnUi(val txtColor: Int, val bgColor: Int)
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): AppWiseDomainsAdapter.ConnectionDetailsViewHolder {
+ val itemBinding =
+ ListItemAppDomainDetailsBinding.inflate(
+ LayoutInflater.from(parent.context),
+ parent,
+ false
+ )
+ adapter = this
+ return ConnectionDetailsViewHolder(itemBinding)
+ }
+
+ override fun onBindViewHolder(
+ holder: AppWiseDomainsAdapter.ConnectionDetailsViewHolder,
+ position: Int
+ ) {
+ val appConnection: AppConnection = getItem(position) ?: return
+ // updates the app-wise connections from network log to AppInfo screen
+ holder.update(appConnection)
+ }
+
+ inner class ConnectionDetailsViewHolder(private val b: ListItemAppDomainDetailsBinding) :
+ RecyclerView.ViewHolder(b.root) {
+ fun update(conn: AppConnection) {
+ displayTransactionDetails(conn)
+ setupClickListeners(conn)
+ }
+
+ private fun displayTransactionDetails(appConnection: AppConnection) {
+ b.acdCount.text = appConnection.count.toString()
+ b.acdDomain.text = appConnection.appOrDnsName
+ if (appConnection.ipAddress.isNotEmpty()) {
+ b.acdIpAddress.visibility = View.VISIBLE
+ b.acdIpAddress.text = beautifyIpString(appConnection.ipAddress)
+ } else {
+ b.acdIpAddress.visibility = View.GONE
+ }
+ updateStatusUi(appConnection.uid, appConnection.appOrDnsName)
+ }
+
+ private fun setupClickListeners(appConn: AppConnection) {
+ b.acdContainer.setOnClickListener {
+ // open bottom sheet to apply domain/ip rules
+ openBottomSheet(appConn)
+ }
+ }
+
+ private fun openBottomSheet(appConn: AppConnection) {
+ if (context !is AppCompatActivity) {
+ Log.w(Logger.LOG_TAG_UI, "Error opening the app conn bottom sheet")
+ return
+ }
+
+ val bottomSheetFragment = AppDomainRulesBottomSheet()
+ // Fix: free-form window crash
+ // all BottomSheetDialogFragment classes created must have a public, no-arg constructor.
+ // the best practice is to simply never define any constructors at all.
+ // so sending the data using Bundles
+ val bundle = Bundle()
+ bundle.putInt(AppDomainRulesBottomSheet.UID, uid)
+ bundle.putString(AppDomainRulesBottomSheet.DOMAIN, appConn.appOrDnsName)
+ bottomSheetFragment.arguments = bundle
+ bottomSheetFragment.dismissListener(adapter, absoluteAdapterPosition)
+ bottomSheetFragment.show(context.supportFragmentManager, bottomSheetFragment.tag)
+ }
+
+ private fun beautifyIpString(d: String): String {
+ // replace two commas in the string to one
+ // add space after all the commas
+ return removeBeginningTrailingCommas(d).replace(",,", ",").replace(",", ", ")
+ }
+
+ private fun updateStatusUi(uid: Int, domain: String?) {
+ if (domain == null) {
+ b.acdFlag.text = context.getString(R.string.ci_no_rule_initial)
+ return
+ }
+
+ val status = DomainRulesManager.getDomainRule(domain, uid)
+ when (status) {
+ DomainRulesManager.Status.NONE -> {
+ b.acdFlag.text = context.getString(R.string.ci_no_rule_initial)
+ }
+ DomainRulesManager.Status.BLOCK -> {
+ b.acdFlag.text = context.getString(R.string.ci_blocked_initial)
+ }
+ DomainRulesManager.Status.TRUST -> {
+ b.acdFlag.text = context.getString(R.string.ci_trust_initial)
+ }
+ }
+
+ // returns the text and background color for the button
+ val t = getToggleBtnUiParams(status)
+ b.acdFlag.setTextColor(t.txtColor)
+ b.acdFlag.backgroundTintList = ColorStateList.valueOf(t.bgColor)
+ }
+
+ private fun getToggleBtnUiParams(id: DomainRulesManager.Status): ToggleBtnUi {
+ return when (id) {
+ DomainRulesManager.Status.NONE -> {
+ ToggleBtnUi(
+ fetchColor(context, R.attr.chipTextNeutral),
+ fetchColor(context, R.attr.chipBgColorNeutral)
+ )
+ }
+ DomainRulesManager.Status.BLOCK -> {
+ ToggleBtnUi(
+ fetchColor(context, R.attr.chipTextNegative),
+ fetchColor(context, R.attr.chipBgColorNegative)
+ )
+ }
+ DomainRulesManager.Status.TRUST -> {
+ ToggleBtnUi(
+ fetchColor(context, R.attr.chipTextPositive),
+ fetchColor(context, R.attr.chipBgColorPositive)
+ )
+ }
+ }
+ }
+ }
+
+ override fun notifyDataset(position: Int) {
+ this.notifyItemChanged(position)
+ }
+}
diff --git a/app/src/full/java/com/celzero/bravedns/adapter/AppConnectionAdapter.kt b/app/src/full/java/com/celzero/bravedns/adapter/AppWiseIpsAdapter.kt
similarity index 87%
rename from app/src/full/java/com/celzero/bravedns/adapter/AppConnectionAdapter.kt
rename to app/src/full/java/com/celzero/bravedns/adapter/AppWiseIpsAdapter.kt
index e1abb1c8e..8a07c6ee7 100644
--- a/app/src/full/java/com/celzero/bravedns/adapter/AppConnectionAdapter.kt
+++ b/app/src/full/java/com/celzero/bravedns/adapter/AppWiseIpsAdapter.kt
@@ -29,18 +29,16 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.celzero.bravedns.R
import com.celzero.bravedns.data.AppConnection
-import com.celzero.bravedns.databinding.ListItemAppConnDetailsBinding
+import com.celzero.bravedns.databinding.ListItemAppIpDetailsBinding
import com.celzero.bravedns.service.IpRulesManager
-import com.celzero.bravedns.ui.bottomsheet.AppConnectionBottomSheet
+import com.celzero.bravedns.ui.bottomsheet.AppIpRulesBottomSheet
import com.celzero.bravedns.util.Logger
import com.celzero.bravedns.util.UIUtils.fetchColor
import com.celzero.bravedns.util.Utilities.removeBeginningTrailingCommas
-class AppConnectionAdapter(val context: Context, val lifecycleOwner: LifecycleOwner, val uid: Int) :
- PagingDataAdapter(
- DIFF_CALLBACK
- ),
- AppConnectionBottomSheet.OnBottomSheetDialogFragmentDismiss {
+class AppWiseIpsAdapter(val context: Context, val lifecycleOwner: LifecycleOwner, val uid: Int) :
+ PagingDataAdapter(DIFF_CALLBACK),
+ AppIpRulesBottomSheet.OnBottomSheetDialogFragmentDismiss {
companion object {
private val DIFF_CALLBACK =
@@ -58,7 +56,7 @@ class AppConnectionAdapter(val context: Context, val lifecycleOwner: LifecycleOw
}
}
- private lateinit var adapter: AppConnectionAdapter
+ private lateinit var adapter: AppWiseIpsAdapter
// ui component to update/toggle the buttons
data class ToggleBtnUi(val txtColor: Int, val bgColor: Int)
@@ -66,19 +64,15 @@ class AppConnectionAdapter(val context: Context, val lifecycleOwner: LifecycleOw
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
- ): AppConnectionAdapter.ConnectionDetailsViewHolder {
+ ): AppWiseIpsAdapter.ConnectionDetailsViewHolder {
val itemBinding =
- ListItemAppConnDetailsBinding.inflate(
- LayoutInflater.from(parent.context),
- parent,
- false
- )
+ ListItemAppIpDetailsBinding.inflate(LayoutInflater.from(parent.context), parent, false)
adapter = this
return ConnectionDetailsViewHolder(itemBinding)
}
override fun onBindViewHolder(
- holder: AppConnectionAdapter.ConnectionDetailsViewHolder,
+ holder: AppWiseIpsAdapter.ConnectionDetailsViewHolder,
position: Int
) {
val appConnection: AppConnection = getItem(position) ?: return
@@ -86,7 +80,7 @@ class AppConnectionAdapter(val context: Context, val lifecycleOwner: LifecycleOw
holder.update(appConnection)
}
- inner class ConnectionDetailsViewHolder(private val b: ListItemAppConnDetailsBinding) :
+ inner class ConnectionDetailsViewHolder(private val b: ListItemAppIpDetailsBinding) :
RecyclerView.ViewHolder(b.root) {
fun update(conn: AppConnection) {
displayTransactionDetails(conn)
@@ -106,16 +100,16 @@ class AppConnectionAdapter(val context: Context, val lifecycleOwner: LifecycleOw
return
}
- val bottomSheetFragment = AppConnectionBottomSheet()
+ val bottomSheetFragment = AppIpRulesBottomSheet()
// Fix: free-form window crash
// all BottomSheetDialogFragment classes created must have a public, no-arg constructor.
// the best practice is to simply never define any constructors at all.
// so sending the data using Bundles
val bundle = Bundle()
- bundle.putInt(AppConnectionBottomSheet.UID, uid)
- bundle.putString(AppConnectionBottomSheet.IP_ADDRESS, appConn.ipAddress)
+ bundle.putInt(AppIpRulesBottomSheet.UID, uid)
+ bundle.putString(AppIpRulesBottomSheet.IP_ADDRESS, appConn.ipAddress)
bundle.putString(
- AppConnectionBottomSheet.DOMAINS,
+ AppIpRulesBottomSheet.DOMAINS,
beautifyDomainString(appConn.appOrDnsName ?: "")
)
bottomSheetFragment.arguments = bundle
diff --git a/app/src/full/java/com/celzero/bravedns/ui/HomeScreenActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/HomeScreenActivity.kt
index 4d6c8f463..8430009f5 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/HomeScreenActivity.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/HomeScreenActivity.kt
@@ -97,12 +97,13 @@ class HomeScreenActivity : AppCompatActivity(R.layout.activity_home_screen) {
private lateinit var biometricPrompt: BiometricPrompt
private lateinit var promptInfo: BiometricPrompt.PromptInfo
- private var biometricPromptRetryCount = 1
+ // private var biometricPromptRetryCount = 1
private var onResumeCalledAlready = false
+
companion object {
private const val ON_RESUME_CALLED_PREFERENCE_KEY = "onResumeCalled"
}
-
+
// TODO - #324 - Usage of isDarkTheme() in all activities.
private fun Context.isDarkThemeOn(): Boolean {
return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
@@ -195,13 +196,15 @@ class HomeScreenActivity : AppCompatActivity(R.layout.activity_home_screen) {
// or another pending operation prevents or disables it
// error code 10 (ERROR_USER_CANCELED), retry once after user cancelled
// the biometric prompt. ref issuetracker.google.com/issues/145231213
- if (
+ // commenting the code below, as the retry is buggy and not working as
+ // expected, have to revisit this code later
+ /* if (
biometricPromptRetryCount > 0 &&
(errorCode == BiometricPrompt.ERROR_CANCELED ||
errorCode == BiometricPrompt.ERROR_USER_CANCELED)
) {
biometricPromptRetryCount--
- biometricPrompt.authenticate(promptInfo)
+ if (isInForeground()) biometricPrompt.authenticate(promptInfo)
} else {
showToastUiCentered(
applicationContext,
@@ -209,14 +212,20 @@ class HomeScreenActivity : AppCompatActivity(R.layout.activity_home_screen) {
Toast.LENGTH_SHORT
)
finish()
- }
+ } */
+ showToastUiCentered(
+ this@HomeScreenActivity,
+ errString.toString(),
+ Toast.LENGTH_SHORT
+ )
+ finish()
}
override fun onAuthenticationSucceeded(
result: BiometricPrompt.AuthenticationResult
) {
super.onAuthenticationSucceeded(result)
- biometricPromptRetryCount = 1
+ // biometricPromptRetryCount = 1
persistentState.biometricAuthTime = SystemClock.elapsedRealtime()
Log.i(LOG_TAG_UI, "Biometric success @ ${System.currentTimeMillis()}")
}
@@ -224,12 +233,11 @@ class HomeScreenActivity : AppCompatActivity(R.layout.activity_home_screen) {
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
showToastUiCentered(
- applicationContext,
+ this@HomeScreenActivity,
getString(R.string.hs_biometeric_failed),
Toast.LENGTH_SHORT
)
Log.i(LOG_TAG_UI, "Biometric authentication failed")
-
// show the biometric prompt again only if the ui is in foreground
if (isInForeground()) biometricPrompt.authenticate(promptInfo)
}
@@ -292,6 +300,8 @@ class HomeScreenActivity : AppCompatActivity(R.layout.activity_home_screen) {
}
private fun showRestoreDialog(uri: Uri) {
+ if (!isInForeground()) return
+
val builder = MaterialAlertDialogBuilder(this)
builder.setTitle(R.string.brbs_restore_dialog_title)
builder.setMessage(R.string.brbs_restore_dialog_message)
@@ -581,6 +591,8 @@ class HomeScreenActivity : AppCompatActivity(R.layout.activity_home_screen) {
title: String,
message: String
) {
+ if (!isInForeground()) return
+
val builder = MaterialAlertDialogBuilder(this)
builder.setTitle(title)
builder.setMessage(message)
diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt
index 16e48f5a8..a064c5a80 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/activity/AppInfoActivity.kt
@@ -97,6 +97,7 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) {
init()
observeNetworkLogSize()
observeAppRules()
+ observeDomainLogSize()
setupClickListeners()
}
@@ -112,12 +113,33 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) {
networkLogsViewModel.getConnectionsCount(uid).observe(this) {
if (it == null) return@observe
- b.aadLogsDetail.text = it.toString()
+ b.aadIpLogsDetail.text = it.toString()
+ }
+ }
+
+ private fun observeDomainLogSize() {
+ networkLogsViewModel.getAppDomainConnectionsCount(uid).observe(this) {
+ if (it == null) return@observe
+
+ b.aadDomainLogsDetail.text = it.toString()
}
}
private fun init() {
- b.aadLogsDetailDesc.text = getString(R.string.lbl_logs).replaceFirstChar { it.uppercase() }
+ val domainTxtDesc =
+ getString(
+ R.string.two_argument_space,
+ getString(R.string.lbl_domain).replaceFirstChar { it.uppercase() },
+ getString(R.string.lbl_logs).replaceFirstChar { it.uppercase() }
+ )
+ val ipTxtDesc =
+ getString(
+ R.string.two_argument_space,
+ getString(R.string.lbl_ip).replaceFirstChar { it.uppercase() },
+ getString(R.string.lbl_logs).replaceFirstChar { it.uppercase() }
+ )
+ b.aadIpLogsDetailDesc.text = ipTxtDesc
+ b.aadDomainLogsDetailDesc.text = domainTxtDesc
io {
val appInfo = FirewallManager.getAppInfoByUid(uid)
// case: app is uninstalled but still available in RethinkDNS database
@@ -347,8 +369,14 @@ class AppInfoActivity : AppCompatActivity(R.layout.activity_app_details) {
b.aadDomainBlockCard.setOnClickListener { openCustomDomainScreen() }
- b.aadLogsCard.setOnClickListener {
- val intent = Intent(this, AppWiseLogsActivity::class.java)
+ b.aadIpLogsCard.setOnClickListener {
+ val intent = Intent(this, AppWiseIpLogsActivity::class.java)
+ intent.putExtra(UID_INTENT_NAME, uid)
+ startActivity(intent)
+ }
+
+ b.aadDomainLogsCard.setOnClickListener {
+ val intent = Intent(this, AppWiseDomainLogsActivity::class.java)
intent.putExtra(UID_INTENT_NAME, uid)
startActivity(intent)
}
diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt
new file mode 100644
index 000000000..2b07d1640
--- /dev/null
+++ b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseDomainLogsActivity.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2024 RethinkDNS and its authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.celzero.bravedns.ui.activity
+
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import android.widget.ImageView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.widget.SearchView
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import by.kirich1409.viewbindingdelegate.viewBinding
+import com.bumptech.glide.Glide
+import com.celzero.bravedns.R
+import com.celzero.bravedns.adapter.AppWiseDomainsAdapter
+import com.celzero.bravedns.database.AppInfo
+import com.celzero.bravedns.database.ConnectionTrackerRepository
+import com.celzero.bravedns.databinding.ActivityAppWiseDomainLogsBinding
+import com.celzero.bravedns.service.FirewallManager
+import com.celzero.bravedns.service.PersistentState
+import com.celzero.bravedns.util.Constants.Companion.INVALID_UID
+import com.celzero.bravedns.util.Themes
+import com.celzero.bravedns.util.Utilities
+import com.celzero.bravedns.viewmodel.AppConnectionsViewModel
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.inject
+import org.koin.androidx.viewmodel.ext.android.viewModel
+
+class AppWiseDomainLogsActivity :
+ AppCompatActivity(R.layout.activity_app_wise_domain_logs), SearchView.OnQueryTextListener {
+ private val b by viewBinding(ActivityAppWiseDomainLogsBinding::bind)
+
+ private val persistentState by inject()
+ private val networkLogsViewModel: AppConnectionsViewModel by viewModel()
+ private val connectionTrackerRepository by inject()
+ private var uid: Int = INVALID_UID
+ private var layoutManager: RecyclerView.LayoutManager? = null
+ private lateinit var appInfo: AppInfo
+
+ private fun Context.isDarkThemeOn(): Boolean {
+ return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
+ Configuration.UI_MODE_NIGHT_YES
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ setTheme(Themes.getCurrentTheme(isDarkThemeOn(), persistentState.theme))
+ super.onCreate(savedInstanceState)
+ uid = intent.getIntExtra(AppInfoActivity.UID_INTENT_NAME, INVALID_UID)
+ if (uid == INVALID_UID) {
+ finish()
+ }
+ init()
+ setAdapter()
+ observeNetworkLogSize()
+ setClickListener()
+ }
+
+ private fun init() {
+ io {
+ val appInfo = FirewallManager.getAppInfoByUid(uid)
+ // case: app is uninstalled but still available in RethinkDNS database
+ if (appInfo == null || uid == INVALID_UID) {
+ uiCtx { finish() }
+ return@io
+ }
+
+ val packages = FirewallManager.getPackageNamesByUid(appInfo.uid)
+ uiCtx {
+ this.appInfo = appInfo
+
+ b.awlAppDetailName.text = appName(packages.count())
+ displayIcon(
+ Utilities.getIcon(this, appInfo.packageName, appInfo.appName),
+ b.awlAppDetailIcon
+ )
+ }
+ }
+ }
+
+ private fun setClickListener() {
+ b.awlDelete.setOnClickListener { showDeleteConnectionsDialog() }
+ b.awlSearch.setOnQueryTextListener(this)
+ }
+
+ private fun appName(packageCount: Int): String {
+ return if (packageCount >= 2) {
+ getString(
+ R.string.ctbs_app_other_apps,
+ appInfo.appName,
+ packageCount.minus(1).toString()
+ )
+ } else {
+ appInfo.appName
+ }
+ }
+
+ private fun displayIcon(drawable: Drawable?, mIconImageView: ImageView) {
+ Glide.with(this).load(drawable).error(Utilities.getDefaultIcon(this)).into(mIconImageView)
+ }
+
+ private fun setAdapter() {
+ networkLogsViewModel.setUid(uid)
+ b.awlRecyclerConnection.setHasFixedSize(true)
+ layoutManager = LinearLayoutManager(this)
+ b.awlRecyclerConnection.layoutManager = layoutManager
+ val recyclerAdapter = AppWiseDomainsAdapter(this, this, uid)
+ networkLogsViewModel.appDomainLogs.observe(this) {
+ recyclerAdapter.submitData(this.lifecycle, it)
+ }
+ b.awlRecyclerConnection.adapter = recyclerAdapter
+ }
+
+ private fun observeNetworkLogSize() {
+ networkLogsViewModel.getConnectionsCount(uid).observe(this) {
+ if (it == null) return@observe
+
+ if (it <= 0) {
+ showNoRulesUi()
+ hideRulesUi()
+ return@observe
+ }
+
+ hideNoRulesUi()
+ showRulesUi()
+ }
+ }
+
+ private fun showNoRulesUi() {
+ b.awlNoRulesRl.visibility = android.view.View.VISIBLE
+ }
+
+ private fun hideRulesUi() {
+ b.awlCardViewTop.visibility = android.view.View.GONE
+ b.awlAppDetailRl.visibility = android.view.View.GONE
+ b.awlRecyclerConnection.visibility = android.view.View.GONE
+ }
+
+ private fun hideNoRulesUi() {
+ b.awlNoRulesRl.visibility = android.view.View.GONE
+ }
+
+ private fun showRulesUi() {
+ b.awlCardViewTop.visibility = android.view.View.VISIBLE
+ b.awlAppDetailRl.visibility = android.view.View.VISIBLE
+ b.awlRecyclerConnection.visibility = android.view.View.VISIBLE
+ }
+
+ override fun onQueryTextSubmit(query: String): Boolean {
+ networkLogsViewModel.setFilter(query, AppConnectionsViewModel.FilterType.DOMAIN)
+ return true
+ }
+
+ override fun onQueryTextChange(query: String): Boolean {
+ Utilities.delay(500, lifecycleScope) {
+ if (!this.isFinishing) {
+ networkLogsViewModel.setFilter(query, AppConnectionsViewModel.FilterType.DOMAIN)
+ }
+ }
+ return true
+ }
+
+ private fun showDeleteConnectionsDialog() {
+ val builder = MaterialAlertDialogBuilder(this)
+ builder.setTitle(R.string.ada_delete_logs_dialog_title)
+ builder.setMessage(R.string.ada_delete_logs_dialog_desc)
+ builder.setCancelable(true)
+ builder.setPositiveButton(getString(R.string.lbl_proceed)) { _, _ -> deleteAppLogs() }
+
+ builder.setNegativeButton(getString(R.string.lbl_cancel)) { _, _ -> }
+ builder.create().show()
+ }
+
+ private fun deleteAppLogs() {
+ io { connectionTrackerRepository.clearLogsByUid(uid) }
+ }
+
+ private fun io(f: suspend () -> Unit): Job {
+ return lifecycleScope.launch(Dispatchers.IO) { f() }
+ }
+
+ private suspend fun uiCtx(f: suspend () -> Unit) {
+ withContext(Dispatchers.Main) { f() }
+ }
+}
diff --git a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseLogsActivity.kt b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt
similarity index 93%
rename from app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseLogsActivity.kt
rename to app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt
index 131969bdb..14005ee67 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseLogsActivity.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/activity/AppWiseIpLogsActivity.kt
@@ -28,10 +28,10 @@ import androidx.recyclerview.widget.RecyclerView
import by.kirich1409.viewbindingdelegate.viewBinding
import com.bumptech.glide.Glide
import com.celzero.bravedns.R
-import com.celzero.bravedns.adapter.AppConnectionAdapter
+import com.celzero.bravedns.adapter.AppWiseIpsAdapter
import com.celzero.bravedns.database.AppInfo
import com.celzero.bravedns.database.ConnectionTrackerRepository
-import com.celzero.bravedns.databinding.ActivityAppWiseLogsBinding
+import com.celzero.bravedns.databinding.ActivityAppWiseIpLogsBinding
import com.celzero.bravedns.service.FirewallManager
import com.celzero.bravedns.service.PersistentState
import com.celzero.bravedns.util.Constants.Companion.INVALID_UID
@@ -46,9 +46,9 @@ import kotlinx.coroutines.withContext
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel
-class AppWiseLogsActivity :
- AppCompatActivity(R.layout.activity_app_wise_logs), SearchView.OnQueryTextListener {
- private val b by viewBinding(ActivityAppWiseLogsBinding::bind)
+class AppWiseIpLogsActivity :
+ AppCompatActivity(R.layout.activity_app_wise_ip_logs), SearchView.OnQueryTextListener {
+ private val b by viewBinding(ActivityAppWiseIpLogsBinding::bind)
private val persistentState by inject()
private val networkLogsViewModel: AppConnectionsViewModel by viewModel()
@@ -123,8 +123,8 @@ class AppWiseLogsActivity :
b.awlRecyclerConnection.setHasFixedSize(true)
layoutManager = LinearLayoutManager(this)
b.awlRecyclerConnection.layoutManager = layoutManager
- val recyclerAdapter = AppConnectionAdapter(this, this, uid)
- networkLogsViewModel.allAppNetworkLogs.observe(this) {
+ val recyclerAdapter = AppWiseIpsAdapter(this, this, uid)
+ networkLogsViewModel.appIpLogs.observe(this) {
recyclerAdapter.submitData(this.lifecycle, it)
}
b.awlRecyclerConnection.adapter = recyclerAdapter
@@ -166,14 +166,14 @@ class AppWiseLogsActivity :
}
override fun onQueryTextSubmit(query: String): Boolean {
- networkLogsViewModel.setFilter(query, AppConnectionsViewModel.FilterType.ALL)
+ networkLogsViewModel.setFilter(query, AppConnectionsViewModel.FilterType.IP)
return true
}
override fun onQueryTextChange(query: String): Boolean {
Utilities.delay(500, lifecycleScope) {
if (!this.isFinishing) {
- networkLogsViewModel.setFilter(query, AppConnectionsViewModel.FilterType.ALL)
+ networkLogsViewModel.setFilter(query, AppConnectionsViewModel.FilterType.IP)
}
}
return true
diff --git a/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppDomainRulesBottomSheet.kt b/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppDomainRulesBottomSheet.kt
new file mode 100644
index 000000000..fbe4be7e4
--- /dev/null
+++ b/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppDomainRulesBottomSheet.kt
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2024 RethinkDNS and its authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.celzero.bravedns.ui.bottomsheet
+
+import android.content.DialogInterface
+import android.content.res.Configuration
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import androidx.lifecycle.lifecycleScope
+import com.celzero.bravedns.R
+import com.celzero.bravedns.adapter.AppWiseDomainsAdapter
+import com.celzero.bravedns.databinding.BottomSheetAppConnectionsBinding
+import com.celzero.bravedns.service.DomainRulesManager
+import com.celzero.bravedns.service.PersistentState
+import com.celzero.bravedns.util.Constants.Companion.INVALID_UID
+import com.celzero.bravedns.util.Logger
+import com.celzero.bravedns.util.Themes.Companion.getBottomsheetCurrentTheme
+import com.celzero.bravedns.util.UIUtils.updateHtmlEncodedText
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.inject
+
+class AppDomainRulesBottomSheet : BottomSheetDialogFragment() {
+ private var _binding: BottomSheetAppConnectionsBinding? = null
+
+ // This property is only valid between onCreateView and onDestroyView.
+ private val b
+ get() = _binding!!
+
+ private val persistentState by inject()
+
+ // listener to inform dataset change to the adapter
+ private var dismissListener: OnBottomSheetDialogFragmentDismiss? = null
+ private var adapter: AppWiseDomainsAdapter? = null
+ private var position: Int = -1
+
+ override fun getTheme(): Int =
+ getBottomsheetCurrentTheme(isDarkThemeOn(), persistentState.theme)
+
+ private var uid: Int = -1
+ private var domain: String = ""
+ private var domainRule: DomainRulesManager.Status = DomainRulesManager.Status.NONE
+
+ companion object {
+ const val UID = "UID"
+ const val DOMAIN = "DOMAIN"
+ }
+
+ private fun isDarkThemeOn(): Boolean {
+ return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
+ Configuration.UI_MODE_NIGHT_YES
+ }
+
+ interface OnBottomSheetDialogFragmentDismiss {
+ fun notifyDataset(position: Int)
+ }
+
+ fun dismissListener(aca: AppWiseDomainsAdapter?, pos: Int) {
+ adapter = aca
+ position = pos
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = BottomSheetAppConnectionsBinding.inflate(inflater, container, false)
+ return b.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ uid = arguments?.getInt(UID) ?: INVALID_UID
+ domain = arguments?.getString(DOMAIN) ?: ""
+
+ dismissListener = adapter
+
+ init()
+ initializeClickListeners()
+ setRulesUi()
+ }
+
+ private fun init() {
+ if (uid == INVALID_UID) {
+ this.dismiss()
+ return
+ }
+ // making use of the same layout used for ip rules, so changing the text and
+ // removing the recycler related changes
+
+ b.bsacIpAddressTv.text = domain
+ b.bsacIpRuleTxt.text = updateHtmlEncodedText(getString(R.string.bsct_block_domain))
+
+ b.bsacDomainRuleTxt.visibility = View.GONE
+ b.bsacDomainLl.visibility = View.GONE
+ }
+
+ private fun setRulesUi() {
+ io {
+ // no need to send port number for the app info screen
+ domainRule = DomainRulesManager.status(domain, uid)
+ Log.d("FirewallManager", "Set selection of ip: $domain, ${domainRule.id}")
+ uiCtx {
+ when (domainRule) {
+ DomainRulesManager.Status.TRUST -> {
+ enableTrustUi()
+ }
+ DomainRulesManager.Status.BLOCK -> {
+ enableBlockUi()
+ }
+ DomainRulesManager.Status.NONE -> {
+ noRuleUi()
+ }
+ }
+ }
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ if (uid == INVALID_UID) {
+ this.dismiss()
+ return
+ }
+ }
+
+ private fun initializeClickListeners() {
+
+ b.blockIcon.setOnClickListener {
+ if (domainRule == DomainRulesManager.Status.BLOCK) {
+ applyDomainRule(DomainRulesManager.Status.NONE)
+ noRuleUi()
+ } else {
+ applyDomainRule(DomainRulesManager.Status.BLOCK)
+ enableBlockUi()
+ }
+ }
+
+ b.trustIcon.setOnClickListener {
+ if (domainRule == DomainRulesManager.Status.TRUST) {
+ applyDomainRule(DomainRulesManager.Status.NONE)
+ noRuleUi()
+ } else {
+ applyDomainRule(DomainRulesManager.Status.TRUST)
+ enableTrustUi()
+ }
+ }
+ }
+
+ private fun applyDomainRule(status: DomainRulesManager.Status) {
+ Log.i(Logger.LOG_TAG_FIREWALL, "domain rule for uid: $uid:$domain (${status.name})")
+ domainRule = status
+
+ // set port number as null for all the rules applied from this screen
+ io {
+ DomainRulesManager.changeStatus(
+ domain,
+ uid,
+ "",
+ DomainRulesManager.DomainType.DOMAIN,
+ status
+ )
+ }
+ }
+
+ override fun onDismiss(dialog: DialogInterface) {
+ super.onDismiss(dialog)
+ dismissListener?.notifyDataset(position)
+ }
+
+ private fun enableTrustUi() {
+ b.trustIcon.setImageDrawable(
+ ContextCompat.getDrawable(requireContext(), R.drawable.ic_trust_accent)
+ )
+ b.blockIcon.setImageDrawable(
+ ContextCompat.getDrawable(requireContext(), R.drawable.ic_block)
+ )
+ }
+
+ private fun enableBlockUi() {
+ b.trustIcon.setImageDrawable(
+ ContextCompat.getDrawable(requireContext(), R.drawable.ic_trust)
+ )
+ b.blockIcon.setImageDrawable(
+ ContextCompat.getDrawable(requireContext(), R.drawable.ic_block_accent)
+ )
+ }
+
+ private fun noRuleUi() {
+ b.trustIcon.setImageDrawable(
+ ContextCompat.getDrawable(requireContext(), R.drawable.ic_trust)
+ )
+ b.blockIcon.setImageDrawable(
+ ContextCompat.getDrawable(requireContext(), R.drawable.ic_block)
+ )
+ }
+
+ private fun io(f: suspend () -> Unit) {
+ lifecycleScope.launch(Dispatchers.IO) { f() }
+ }
+
+ private suspend fun uiCtx(f: suspend () -> Unit) {
+ withContext(Dispatchers.Main) { f() }
+ }
+}
diff --git a/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppConnectionBottomSheet.kt b/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppIpRulesBottomSheet.kt
similarity index 96%
rename from app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppConnectionBottomSheet.kt
rename to app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppIpRulesBottomSheet.kt
index 0834bceed..d4e8a77d0 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppConnectionBottomSheet.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/bottomsheet/AppIpRulesBottomSheet.kt
@@ -25,9 +25,8 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.celzero.bravedns.R
-import com.celzero.bravedns.adapter.AppConnectionAdapter
+import com.celzero.bravedns.adapter.AppWiseIpsAdapter
import com.celzero.bravedns.adapter.DomainRulesBtmSheetAdapter
-import com.celzero.bravedns.data.AppConfig
import com.celzero.bravedns.databinding.BottomSheetAppConnectionsBinding
import com.celzero.bravedns.service.IpRulesManager
import com.celzero.bravedns.service.PersistentState
@@ -42,7 +41,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.inject
-class AppConnectionBottomSheet : BottomSheetDialogFragment() {
+class AppIpRulesBottomSheet : BottomSheetDialogFragment() {
private var _binding: BottomSheetAppConnectionsBinding? = null
// This property is only valid between onCreateView and onDestroyView.
@@ -50,11 +49,10 @@ class AppConnectionBottomSheet : BottomSheetDialogFragment() {
get() = _binding!!
private val persistentState by inject()
- private val appConfig by inject()
// listener to inform dataset change to the adapter
private var dismissListener: OnBottomSheetDialogFragmentDismiss? = null
- private var adapter: AppConnectionAdapter? = null
+ private var adapter: AppWiseIpsAdapter? = null
private var position: Int = -1
override fun getTheme(): Int =
@@ -80,7 +78,7 @@ class AppConnectionBottomSheet : BottomSheetDialogFragment() {
fun notifyDataset(position: Int)
}
- fun dismissListener(aca: AppConnectionAdapter?, pos: Int) {
+ fun dismissListener(aca: AppWiseIpsAdapter?, pos: Int) {
adapter = aca
position = pos
}
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomDomainFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomDomainFragment.kt
index ca52e77c7..1c388a0ea 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomDomainFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomDomainFragment.kt
@@ -219,12 +219,12 @@ class CustomDomainFragment :
)
}
}
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
+
dialog.setCancelable(true)
dialog.window?.attributes = lp
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomIpFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomIpFragment.kt
index c0a98e4ec..f3ac2537c 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomIpFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/CustomIpFragment.kt
@@ -182,12 +182,12 @@ class CustomIpFragment : Fragment(R.layout.fragment_custom_ip), SearchView.OnQue
dialog.setTitle(getString(R.string.ci_dialog_title))
val dBind = DialogAddCustomIpBinding.inflate(layoutInflater)
dialog.setContentView(dBind.root)
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
+
dialog.setCancelable(true)
dialog.window?.attributes = lp
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsCryptListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsCryptListFragment.kt
index a805b92aa..a7f566948 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsCryptListFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsCryptListFragment.kt
@@ -113,12 +113,12 @@ class DnsCryptListFragment : Fragment(R.layout.fragment_dns_crypt_list) {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setTitle(getString(R.string.cd_dns_crypt_dialog_title))
dialog.setContentView(dialogBinding.root)
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
+
dialog.setCancelable(true)
dialog.window?.attributes = lp
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt
index 0573032b0..22e7f41ac 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/DnsProxyListFragment.kt
@@ -94,12 +94,12 @@ class DnsProxyListFragment : Fragment(R.layout.fragment_dns_proxy_list) {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setTitle(getString(R.string.cd_custom_dns_proxy_title))
dialog.setContentView(dialogBinding.root)
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
+
dialog.setCancelable(true)
// TODO: figure out why window maybe null
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/DoTListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/DoTListFragment.kt
index 6d887f828..2b8e0122c 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/DoTListFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/DoTListFragment.kt
@@ -80,12 +80,12 @@ class DoTListFragment : Fragment(R.layout.fragment_dot_list) {
dialog.setTitle(getString(R.string.cd_custom_doh_dialog_title))
val dialogBinding = DialogSetCustomDohBinding.inflate(layoutInflater)
dialog.setContentView(dialogBinding.root)
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
+
dialog.setCancelable(true)
dialog.window?.attributes = lp
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/DohListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/DohListFragment.kt
index 9fe2ba61a..ec24327b3 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/DohListFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/DohListFragment.kt
@@ -88,12 +88,11 @@ class DohListFragment : Fragment(R.layout.fragment_doh_list) {
dialog.setTitle(getString(R.string.cd_custom_doh_dialog_title))
val dialogBinding = DialogSetCustomDohBinding.inflate(layoutInflater)
dialog.setContentView(dialogBinding.root)
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
dialog.setCancelable(true)
dialog.window?.attributes = lp
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/ODoHListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/ODoHListFragment.kt
index 3edeadba0..85a97a8c5 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/ODoHListFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/ODoHListFragment.kt
@@ -82,12 +82,12 @@ class ODoHListFragment : Fragment(R.layout.fragment_odoh_list) {
dialog.setTitle(getString(R.string.cd_custom_doh_dialog_title))
val dialogBinding = DialogSetCustomOdohBinding.inflate(layoutInflater)
dialog.setContentView(dialogBinding.root)
-
+ dialog.show()
val lp = WindowManager.LayoutParams()
lp.copyFrom(dialog.window?.attributes)
lp.width = WindowManager.LayoutParams.MATCH_PARENT
lp.height = WindowManager.LayoutParams.WRAP_CONTENT
- dialog.show()
+
dialog.setCancelable(true)
dialog.window?.attributes = lp
diff --git a/app/src/full/java/com/celzero/bravedns/ui/fragment/RethinkListFragment.kt b/app/src/full/java/com/celzero/bravedns/ui/fragment/RethinkListFragment.kt
index d20524204..79e488fc8 100644
--- a/app/src/full/java/com/celzero/bravedns/ui/fragment/RethinkListFragment.kt
+++ b/app/src/full/java/com/celzero/bravedns/ui/fragment/RethinkListFragment.kt
@@ -181,8 +181,8 @@ class RethinkListFragment : Fragment(R.layout.fragment_rethink_list) {
private fun updateMaxSwitchUi() {
ui {
- var endpointUrl: String? = ""
- ioCtx { endpointUrl = appConfig.getRethinkPlusEndpoint().url }
+ var endpointUrl: String? = null
+ ioCtx { endpointUrl = appConfig.getRethinkPlusEndpoint()?.url }
updateRethinkRadioUi(isMax = endpointUrl?.contains(MAX_ENDPOINT) == true)
}
}
diff --git a/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt b/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt
index 337eb7000..1dfe03812 100644
--- a/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt
+++ b/app/src/full/java/com/celzero/bravedns/viewmodel/AppConnectionsViewModel.kt
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2024 RethinkDNS and its authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.celzero.bravedns.viewmodel
import androidx.lifecycle.LiveData
@@ -15,14 +30,14 @@ import com.celzero.bravedns.database.ConnectionTrackerDAO
import com.celzero.bravedns.util.Constants
class AppConnectionsViewModel(private val nwlogDao: ConnectionTrackerDAO) : ViewModel() {
- private var filter: MutableLiveData = MutableLiveData()
- private var allLogsFilter: MutableLiveData = MutableLiveData()
+ private var ipFilter: MutableLiveData = MutableLiveData()
+ private var domainFilter: MutableLiveData = MutableLiveData()
private var uid: Int = Constants.INVALID_UID
private val pagingConfig: PagingConfig
init {
- filter.value = ""
- allLogsFilter.value = ""
+ ipFilter.value = ""
+ domainFilter.value = ""
pagingConfig =
PagingConfig(
@@ -36,31 +51,46 @@ class AppConnectionsViewModel(private val nwlogDao: ConnectionTrackerDAO) : View
}
enum class FilterType {
- OFFSET,
- ALL
+ IP,
+ DOMAIN
}
- val allAppNetworkLogs = allLogsFilter.switchMap { input -> fetchAllNetworkLogs(uid, input) }
+ val appIpLogs = ipFilter.switchMap { input -> fetchIpLogs(uid, input) }
+ val appDomainLogs = domainFilter.switchMap { input -> fetchAppDomainLogs(uid, input) }
- private fun fetchAllNetworkLogs(uid: Int, input: String): LiveData> {
+ private fun fetchIpLogs(uid: Int, input: String): LiveData> {
return if (input.isEmpty()) {
- Pager(pagingConfig) { nwlogDao.getAllLogs(uid) }.liveData.cachedIn(viewModelScope)
- } else {
- Pager(pagingConfig) { nwlogDao.getAllLogsFiltered(uid, "%$input%") }
- .liveData
- .cachedIn(viewModelScope)
- }
+ Pager(pagingConfig) { nwlogDao.getAppIpLogs(uid) }
+ } else {
+ Pager(pagingConfig) { nwlogDao.getAppIpLogsFiltered(uid, "%$input%") }
+ }
+ .liveData
+ .cachedIn(viewModelScope)
+ }
+
+ private fun fetchAppDomainLogs(uid: Int, input: String): LiveData> {
+ return if (input.isEmpty()) {
+ Pager(pagingConfig) { nwlogDao.getAppDomainLogs(uid) }
+ } else {
+ Pager(pagingConfig) { nwlogDao.getAppDomainLogsFiltered(uid, "%$input%") }
+ }
+ .liveData
+ .cachedIn(viewModelScope)
}
fun getConnectionsCount(uid: Int): LiveData {
return nwlogDao.getAppConnectionsCount(uid)
}
+ fun getAppDomainConnectionsCount(uid: Int): LiveData {
+ return nwlogDao.getAppDomainConnectionsCount(uid)
+ }
+
fun setFilter(input: String, filterType: FilterType) {
- if (filterType == FilterType.OFFSET) {
- this.filter.postValue(input)
+ if (filterType == FilterType.IP) {
+ this.ipFilter.postValue(input)
} else {
- this.allLogsFilter.postValue(input)
+ this.domainFilter.postValue(input)
}
}
diff --git a/app/src/full/res/layout/activity_app_details.xml b/app/src/full/res/layout/activity_app_details.xml
index fc3a05da2..b8cea9a4a 100644
--- a/app/src/full/res/layout/activity_app_details.xml
+++ b/app/src/full/res/layout/activity_app_details.xml
@@ -422,7 +422,7 @@
+
+
+
+
+
+
+
+
+
+
+
+ android:elevation="5dp"
+ app:cardCornerRadius="16dp">
+ android:text="@string/pause_desc"
+ android:textSize="@dimen/small_font_subheading_text" />
diff --git a/app/src/full/res/layout/activity_tcp_proxy.xml b/app/src/full/res/layout/activity_tcp_proxy.xml
index ce54f1dab..c0efc4ed8 100644
--- a/app/src/full/res/layout/activity_tcp_proxy.xml
+++ b/app/src/full/res/layout/activity_tcp_proxy.xml
@@ -102,9 +102,9 @@
android:layout_gravity="center_vertical"
android:layout_marginStart="2dp"
android:layout_marginTop="5dp"
+ android:layout_toEndOf="@id/tcp_proxy_icon"
android:padding="5dp"
- android:textColor="?attr/secondaryTextColor"
- android:layout_toEndOf="@id/tcp_proxy_icon" />
+ android:textColor="?attr/secondaryTextColor" />
+ android:textColor="?attr/accentGood"
+ android:visibility="gone" />
diff --git a/app/src/full/res/layout/bottom_sheet_conn_track.xml b/app/src/full/res/layout/bottom_sheet_conn_track.xml
index b1ed27cf2..7dce4fbff 100644
--- a/app/src/full/res/layout/bottom_sheet_conn_track.xml
+++ b/app/src/full/res/layout/bottom_sheet_conn_track.xml
@@ -241,10 +241,10 @@
android:fontFamily="sans-serif-light"
android:gravity="center"
android:maxLines="1"
- android:visibility="gone"
android:singleLine="true"
android:textColor="?attr/primaryLightColorText"
- android:textSize="@dimen/default_font_text_view" />
+ android:textSize="@dimen/default_font_text_view"
+ android:visibility="gone" />
diff --git a/app/src/full/res/layout/bottom_sheet_firewall_sort_filter.xml b/app/src/full/res/layout/bottom_sheet_firewall_sort_filter.xml
index dcd49aaf3..6e9e764c6 100644
--- a/app/src/full/res/layout/bottom_sheet_firewall_sort_filter.xml
+++ b/app/src/full/res/layout/bottom_sheet_firewall_sort_filter.xml
@@ -62,9 +62,9 @@
+ android:padding="10dp"
+ android:weightSum="1">
@@ -87,9 +87,9 @@
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_weight="0.7"
+ android:background="@drawable/rounded_corners_button_accent"
android:maxHeight="40dp"
android:minHeight="40dp"
- android:background="@drawable/rounded_corners_button_accent"
android:padding="5dp"
android:text="@string/lbl_apply"
android:textColor="?attr/chipTextColor" />
diff --git a/app/src/full/res/layout/bottom_sheet_home_screen.xml b/app/src/full/res/layout/bottom_sheet_home_screen.xml
index 96e81313a..90393f3b8 100644
--- a/app/src/full/res/layout/bottom_sheet_home_screen.xml
+++ b/app/src/full/res/layout/bottom_sheet_home_screen.xml
@@ -40,7 +40,6 @@
+ android:visibility="visible"
+ app:drawableStartCompat="@drawable/dis_allowed" />
diff --git a/app/src/full/res/layout/bottom_sheet_rethink_list.xml b/app/src/full/res/layout/bottom_sheet_rethink_list.xml
index b63595981..8643c5c0c 100644
--- a/app/src/full/res/layout/bottom_sheet_rethink_list.xml
+++ b/app/src/full/res/layout/bottom_sheet_rethink_list.xml
@@ -36,9 +36,9 @@
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="10dp"
- android:background="?android:attr/selectableItemBackground"
android:layout_margin="10dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:padding="10dp"
android:text="Click here to configure blocklists."
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/default_font_text_view"
diff --git a/app/src/full/res/layout/connection_transaction_row.xml b/app/src/full/res/layout/connection_transaction_row.xml
index ea359b50d..a72897e06 100644
--- a/app/src/full/res/layout/connection_transaction_row.xml
+++ b/app/src/full/res/layout/connection_transaction_row.xml
@@ -109,12 +109,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:alpha="0.9"
android:ellipsize="none"
android:gravity="center"
+ android:maxWidth="32dp"
android:maxHeight="16dp"
- android:alpha="0.9"
android:minWidth="16dp"
- android:maxWidth="32dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textSize="26sp"
diff --git a/app/src/full/res/layout/dialog_add_custom_domain.xml b/app/src/full/res/layout/dialog_add_custom_domain.xml
index 1f9019748..25b9e7743 100644
--- a/app/src/full/res/layout/dialog_add_custom_domain.xml
+++ b/app/src/full/res/layout/dialog_add_custom_domain.xml
@@ -84,14 +84,14 @@
@@ -42,8 +42,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
- android:text="@string/firewall_rules"
android:drawablePadding="15dp"
+ android:text="@string/firewall_rules"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/heading_font_text_view" />
diff --git a/app/src/full/res/layout/dialog_ip_details_layout.xml b/app/src/full/res/layout/dialog_ip_details_layout.xml
index 86974fb18..56cec0670 100644
--- a/app/src/full/res/layout/dialog_ip_details_layout.xml
+++ b/app/src/full/res/layout/dialog_ip_details_layout.xml
@@ -24,8 +24,8 @@
@@ -40,8 +40,8 @@
android:id="@+id/ip_details_fqdn_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:padding="5dp"
android:layout_gravity="center_vertical"
+ android:padding="5dp"
android:text="@string/firewall_rules"
android:textColor="?attr/primaryLightColorText"
android:textIsSelectable="true"
@@ -54,10 +54,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
- android:textSize="@dimen/large_font_text_view"
+ android:padding="5dp"
android:textColor="?attr/primaryTextColor"
android:textIsSelectable="true"
- android:padding="5dp" />
+ android:textSize="@dimen/large_font_text_view" />
diff --git a/app/src/full/res/layout/dialog_set_custom_doh.xml b/app/src/full/res/layout/dialog_set_custom_doh.xml
index 8e86c675a..239d733e2 100644
--- a/app/src/full/res/layout/dialog_set_custom_doh.xml
+++ b/app/src/full/res/layout/dialog_set_custom_doh.xml
@@ -74,9 +74,9 @@
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:buttonTint="?attr/accentGood"
+ android:foregroundTint="?attr/accentGood"
android:paddingStart="10dp"
android:paddingEnd="10dp"
- android:foregroundTint="?attr/accentGood"
android:text="@string/cd_doh_dialog_checkbox_desc"
app:layout_constraintTop_toBottomOf="@id/text_input_layout1" />
diff --git a/app/src/full/res/layout/dialog_set_custom_odoh.xml b/app/src/full/res/layout/dialog_set_custom_odoh.xml
index bfdc39a80..2b21137e5 100644
--- a/app/src/full/res/layout/dialog_set_custom_odoh.xml
+++ b/app/src/full/res/layout/dialog_set_custom_odoh.xml
@@ -83,8 +83,8 @@
android:layout_marginBottom="10dp"
android:inputType="textUri"
android:maxLines="2"
- android:text="https://"
android:padding="10dp"
+ android:text="https://"
android:textColor="?attr/primaryTextColor"
android:textSize="@dimen/large_font_text_view"
app:layout_constraintRight_toLeftOf="parent"
diff --git a/app/src/full/res/layout/dialog_set_dns_crypt.xml b/app/src/full/res/layout/dialog_set_dns_crypt.xml
index cb2caf787..8378dcf7e 100644
--- a/app/src/full/res/layout/dialog_set_dns_crypt.xml
+++ b/app/src/full/res/layout/dialog_set_dns_crypt.xml
@@ -108,8 +108,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
- android:textSize="@dimen/default_font_text_view"
android:textColor="@color/colorRed_A400"
+ android:textSize="@dimen/default_font_text_view"
app:layout_constraintTop_toBottomOf="@id/text_input_layout3" />
@@ -118,19 +118,18 @@
diff --git a/app/src/full/res/layout/dialog_set_dns_proxy.xml b/app/src/full/res/layout/dialog_set_dns_proxy.xml
index 4b6de3d68..edbb1bd2c 100644
--- a/app/src/full/res/layout/dialog_set_dns_proxy.xml
+++ b/app/src/full/res/layout/dialog_set_dns_proxy.xml
@@ -20,9 +20,9 @@
android:id="@+id/dialog_dns_proxy_spinner_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
android:orientation="horizontal"
android:padding="10dp"
- android:layout_marginTop="10dp"
android:weightSum="1">
diff --git a/app/src/full/res/layout/fragment_dns_crypt_list.xml b/app/src/full/res/layout/fragment_dns_crypt_list.xml
index 287e6294e..c8484495f 100644
--- a/app/src/full/res/layout/fragment_dns_crypt_list.xml
+++ b/app/src/full/res/layout/fragment_dns_crypt_list.xml
@@ -34,11 +34,11 @@
android:layout_marginEnd="15dp"
android:background="@drawable/rectangle_border_background"
android:drawablePadding="5dp"
- android:paddingStart="10dp"
- android:paddingEnd="10dp"
android:fontFamily="sans-serif-smallcaps"
android:gravity="center"
+ android:paddingStart="10dp"
android:paddingTop="5dp"
+ android:paddingEnd="10dp"
android:paddingBottom="5dp"
android:text="@string/cd_dnscrypt_relay_heading"
android:textColor="?attr/secondaryTextColor"
diff --git a/app/src/full/res/layout/fragment_dns_proxy_list.xml b/app/src/full/res/layout/fragment_dns_proxy_list.xml
index 7c3d7fc67..5f3ab5bfc 100644
--- a/app/src/full/res/layout/fragment_dns_proxy_list.xml
+++ b/app/src/full/res/layout/fragment_dns_proxy_list.xml
@@ -8,9 +8,9 @@
android:id="@+id/recycler_dns_proxy_connections"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:clipToPadding="false"
android:nestedScrollingEnabled="true"
android:paddingBottom="50dp"
- android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -21,12 +21,12 @@
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="30dp"
- android:src="@drawable/ic_fab_without_border"
+ android:contentDescription="New"
android:padding="10dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:src="@drawable/ic_fab_without_border"
app:fabSize="normal"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
- android:contentDescription="New" />
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/full/res/layout/fragment_doh_list.xml b/app/src/full/res/layout/fragment_doh_list.xml
index 1b9d91d40..bea1d808b 100644
--- a/app/src/full/res/layout/fragment_doh_list.xml
+++ b/app/src/full/res/layout/fragment_doh_list.xml
@@ -8,9 +8,9 @@
android:id="@+id/recycler_doh_connections"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingBottom="50dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="true"
+ android:paddingBottom="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -21,12 +21,12 @@
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="30dp"
- android:src="@drawable/ic_fab_without_border"
+ android:contentDescription="New"
android:padding="10dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:src="@drawable/ic_fab_without_border"
app:fabSize="normal"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
- android:contentDescription="New" />
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/full/res/layout/fragment_dot_list.xml b/app/src/full/res/layout/fragment_dot_list.xml
index 1cb369337..6fbf0dad7 100644
--- a/app/src/full/res/layout/fragment_dot_list.xml
+++ b/app/src/full/res/layout/fragment_dot_list.xml
@@ -8,9 +8,9 @@
android:id="@+id/recycler_dot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingBottom="50dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="true"
+ android:paddingBottom="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -21,12 +21,12 @@
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="30dp"
- android:src="@drawable/ic_fab_without_border"
+ android:contentDescription="New"
android:padding="10dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:src="@drawable/ic_fab_without_border"
app:fabSize="normal"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
- android:contentDescription="New" />
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/full/res/layout/fragment_home_screen.xml b/app/src/full/res/layout/fragment_home_screen.xml
index 42dbd0771..bdd2bde65 100644
--- a/app/src/full/res/layout/fragment_home_screen.xml
+++ b/app/src/full/res/layout/fragment_home_screen.xml
@@ -17,9 +17,9 @@
+ android:gravity="center"
+ android:text="@string/app_name_small_case"
+ android:textStyle="bold" />
diff --git a/app/src/full/res/layout/fragment_odoh_list.xml b/app/src/full/res/layout/fragment_odoh_list.xml
index 3f5e319be..8f066764f 100644
--- a/app/src/full/res/layout/fragment_odoh_list.xml
+++ b/app/src/full/res/layout/fragment_odoh_list.xml
@@ -8,9 +8,9 @@
android:id="@+id/recycler_odoh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingBottom="50dp"
android:clipToPadding="false"
android:nestedScrollingEnabled="true"
+ android:paddingBottom="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -21,12 +21,12 @@
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="30dp"
- android:src="@drawable/ic_fab_without_border"
+ android:contentDescription="New"
android:padding="10dp"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
+ android:src="@drawable/ic_fab_without_border"
app:fabSize="normal"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
- android:contentDescription="New" />
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
diff --git a/app/src/full/res/layout/fragment_rethink_list.xml b/app/src/full/res/layout/fragment_rethink_list.xml
index fa660c724..371c69aca 100644
--- a/app/src/full/res/layout/fragment_rethink_list.xml
+++ b/app/src/full/res/layout/fragment_rethink_list.xml
@@ -110,8 +110,8 @@
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
android:layout_gravity="center"
+ android:layout_marginTop="20dp"
android:gravity="center"
android:orientation="horizontal">
@@ -122,8 +122,8 @@
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:button="@null"
- android:drawablePadding="5dp"
android:drawableBottom="?android:attr/listChoiceIndicatorSingle"
+ android:drawablePadding="5dp"
android:gravity="center_horizontal|bottom"
android:text="@string/radio_sky_btn" />
@@ -135,8 +135,8 @@
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:button="@null"
- android:drawablePadding="5dp"
android:drawableBottom="?android:attr/listChoiceIndicatorSingle"
+ android:drawablePadding="5dp"
android:gravity="center_horizontal|bottom"
android:text="@string/radio_max_btn" />
@@ -145,11 +145,11 @@
android:id="@+id/frl_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
android:alpha="0.7"
android:gravity="center"
android:nestedScrollingEnabled="true"
android:padding="10dp"
- android:layout_marginBottom="10dp"
android:textColor="?attr/primaryLightColorText"
android:textSize="@dimen/default_font_text_view"
android:textStyle="normal"
diff --git a/app/src/full/res/layout/item_chip_filter.xml b/app/src/full/res/layout/item_chip_filter.xml
index 1094ff098..80b234f2b 100644
--- a/app/src/full/res/layout/item_chip_filter.xml
+++ b/app/src/full/res/layout/item_chip_filter.xml
@@ -4,12 +4,12 @@
style="@style/ThinnerChip.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAlignment="center"
android:layout_margin="3dp"
android:padding="2dp"
- app:chipIconEnabled="true"
- app:chipIconSize="15dp"
- app:iconStartPadding="3dp"
+ android:textAlignment="center"
android:textSize="@dimen/default_font_text_view"
app:checkedIconTint="?attr/primaryTextColor"
- app:chipBackgroundColor="@drawable/bg_chip_state_list" />
+ app:chipBackgroundColor="@drawable/bg_chip_state_list"
+ app:chipIconEnabled="true"
+ app:chipIconSize="15dp"
+ app:iconStartPadding="3dp" />
diff --git a/app/src/full/res/layout/list_item_app_domain_details.xml b/app/src/full/res/layout/list_item_app_domain_details.xml
new file mode 100644
index 000000000..3c8a7dc26
--- /dev/null
+++ b/app/src/full/res/layout/list_item_app_domain_details.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/full/res/layout/list_item_app_conn_details.xml b/app/src/full/res/layout/list_item_app_ip_details.xml
similarity index 98%
rename from app/src/full/res/layout/list_item_app_conn_details.xml
rename to app/src/full/res/layout/list_item_app_ip_details.xml
index 8da3b5d49..16503cbed 100644
--- a/app/src/full/res/layout/list_item_app_conn_details.xml
+++ b/app/src/full/res/layout/list_item_app_ip_details.xml
@@ -9,8 +9,8 @@
+ android:animateLayoutChanges="true"
+ android:minHeight="50dp">
diff --git a/app/src/full/res/layout/list_item_custom_domain.xml b/app/src/full/res/layout/list_item_custom_domain.xml
index 03274429c..038eb9a9c 100644
--- a/app/src/full/res/layout/list_item_custom_domain.xml
+++ b/app/src/full/res/layout/list_item_custom_domain.xml
@@ -59,8 +59,8 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
- android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
+ android:layout_marginEnd="5dp"
android:layout_toStartOf="@id/custom_domain_expand_icon"
android:alpha="0.5"
android:src="@drawable/ic_edit_icon_grey" />
diff --git a/app/src/full/res/layout/list_item_custom_ip.xml b/app/src/full/res/layout/list_item_custom_ip.xml
index 3ee52a910..339731e76 100644
--- a/app/src/full/res/layout/list_item_custom_ip.xml
+++ b/app/src/full/res/layout/list_item_custom_ip.xml
@@ -70,8 +70,8 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
- android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
+ android:layout_marginEnd="5dp"
android:layout_toStartOf="@id/custom_ip_expand_icon"
android:alpha="0.5"
android:src="@drawable/ic_edit_icon_grey" />
diff --git a/app/src/full/res/layout/list_item_firewall_app.xml b/app/src/full/res/layout/list_item_firewall_app.xml
index fe688a2a4..7626ecc33 100644
--- a/app/src/full/res/layout/list_item_firewall_app.xml
+++ b/app/src/full/res/layout/list_item_firewall_app.xml
@@ -98,11 +98,11 @@
android:id="@+id/firewall_app_toggle_mobile_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
- android:layout_alignParentEnd="true"
android:maxWidth="24dp"
android:maxHeight="24dp"
android:padding="5dp"
diff --git a/app/src/full/res/layout/transaction_row.xml b/app/src/full/res/layout/transaction_row.xml
index 8fe9d0fd5..e281fe634 100644
--- a/app/src/full/res/layout/transaction_row.xml
+++ b/app/src/full/res/layout/transaction_row.xml
@@ -20,9 +20,9 @@
-
+
diff --git a/app/src/main/java/com/celzero/bravedns/data/AppConfig.kt b/app/src/main/java/com/celzero/bravedns/data/AppConfig.kt
index 354373f9a..2c2ca5fe4 100644
--- a/app/src/main/java/com/celzero/bravedns/data/AppConfig.kt
+++ b/app/src/main/java/com/celzero/bravedns/data/AppConfig.kt
@@ -735,7 +735,7 @@ internal constructor(
}
}
- suspend fun getRethinkPlusEndpoint(): RethinkDnsEndpoint {
+ suspend fun getRethinkPlusEndpoint(): RethinkDnsEndpoint? {
return rethinkDnsEndpointRepository.getRethinkPlusEndpoint()
}
diff --git a/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt b/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt
index 2f750f1c5..055f45a74 100644
--- a/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt
+++ b/app/src/main/java/com/celzero/bravedns/database/ConnectionTrackerDAO.kt
@@ -91,16 +91,29 @@ interface ConnectionTrackerDAO {
@Query(
"SELECT uid, ipAddress, port, COUNT(ipAddress) as count, '' as flag, 0 as blocked, GROUP_CONCAT(DISTINCT dnsQuery) as appOrDnsName FROM ConnectionTracker WHERE uid = :uid GROUP BY ipAddress, uid, port ORDER BY count DESC"
)
- fun getAllLogs(uid: Int): PagingSource
+ fun getAppIpLogs(uid: Int): PagingSource
@Query(
"SELECT uid, ipAddress, port, COUNT(ipAddress) as count, '' as flag, 0 as blocked, GROUP_CONCAT(DISTINCT dnsQuery) as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and ipAddress like :query GROUP BY ipAddress, uid, port ORDER BY count DESC"
)
- fun getAllLogsFiltered(uid: Int, query: String): PagingSource
+ fun getAppIpLogsFiltered(uid: Int, query: String): PagingSource
+
+ @Query(
+ "SELECT uid, GROUP_CONCAT(DISTINCT ipAddress) as ipAddress, port, COUNT(dnsQuery) as count, '' as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and dnsQuery != '' GROUP BY dnsQuery ORDER BY count DESC"
+ )
+ fun getAppDomainLogs(uid: Int): PagingSource
+
+ @Query(
+ "SELECT uid, GROUP_CONCAT(DISTINCT ipAddress) as ipAddress, port, COUNT(dnsQuery) as count, '' as flag, 0 as blocked, dnsQuery as appOrDnsName FROM ConnectionTracker WHERE uid = :uid and dnsQuery != '' and dnsQuery like :query GROUP BY dnsQuery ORDER BY count DESC"
+ )
+ fun getAppDomainLogsFiltered(uid: Int, query: String): PagingSource
@Query("select count(DISTINCT(ipAddress)) from ConnectionTracker where uid = :uid")
fun getAppConnectionsCount(uid: Int): LiveData
+ @Query("select count(DISTINCT(dnsQuery)) from ConnectionTracker where uid = :uid")
+ fun getAppDomainConnectionsCount(uid: Int): LiveData
+
@Query(
"select * from ConnectionTracker where blockedByRule in (:filter) and isBlocked = 1 order by id desc LIMIT $MAX_LOGS"
)
diff --git a/app/src/main/java/com/celzero/bravedns/database/RefreshDatabase.kt b/app/src/main/java/com/celzero/bravedns/database/RefreshDatabase.kt
index f035820a1..fde91fc19 100644
--- a/app/src/main/java/com/celzero/bravedns/database/RefreshDatabase.kt
+++ b/app/src/main/java/com/celzero/bravedns/database/RefreshDatabase.kt
@@ -56,13 +56,13 @@ import com.celzero.bravedns.util.Utilities.getActivityPendingIntent
import com.celzero.bravedns.util.Utilities.isAtleastO
import com.celzero.bravedns.util.Utilities.isAtleastT
import com.celzero.bravedns.util.Utilities.isNonApp
+import java.util.concurrent.TimeUnit
+import kotlin.random.Random
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
-import java.util.concurrent.TimeUnit
-import kotlin.random.Random
class RefreshDatabase
internal constructor(
@@ -152,9 +152,6 @@ internal constructor(
)
val trackedApps = FirewallManager.getAllApps()
- if (trackedApps.isEmpty()) {
- notifyEmptyFirewallRules()
- }
// installedPackages includes apps which are disabled by the user
val installedPackages: List =
if (isAtleastT()) {
@@ -202,6 +199,7 @@ internal constructor(
Log.e(LOG_TAG_APP_DB, e.message, e)
throw e
} finally {
+ notifyEmptyFirewallRulesIfNeeded()
a.cb()
}
}
@@ -648,7 +646,12 @@ internal constructor(
notificationManager.notify(NOTIF_CHANNEL_ID_FIREWALL_ALERTS, app.uid, builder.build())
}
- private fun notifyEmptyFirewallRules() {
+ private suspend fun notifyEmptyFirewallRulesIfNeeded() {
+ val trackedApps = FirewallManager.getAllApps()
+ if (trackedApps.isNotEmpty()) {
+ return
+ }
+
val intent = Intent(ctx, HomeScreenActivity::class.java)
val nm = ctx.getSystemService(VpnService.NOTIFICATION_SERVICE) as NotificationManager
val pendingIntent =
diff --git a/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointDao.kt b/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointDao.kt
index cae4404a4..29e46de37 100644
--- a/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointDao.kt
+++ b/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointDao.kt
@@ -78,7 +78,7 @@ interface RethinkDnsEndpointDao {
@Query("select count(*) from RethinkDnsEndpoint") fun getCount(): Int
@Query("select * from RethinkDnsEndpoint where name = :plus and uid = $MISSING_UID")
- fun getRethinkPlusEndpoint(plus: String = RETHINK_PLUS): RethinkDnsEndpoint
+ fun getRethinkPlusEndpoint(plus: String = RETHINK_PLUS): RethinkDnsEndpoint?
@Query("update RethinkDnsEndpoint set isActive = 1 where uid = $MISSING_UID and name = :plus")
fun setRethinkPlus(plus: String = RETHINK_PLUS)
diff --git a/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointRepository.kt b/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointRepository.kt
index e6c371c7c..1bc6878ed 100644
--- a/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointRepository.kt
+++ b/app/src/main/java/com/celzero/bravedns/database/RethinkDnsEndpointRepository.kt
@@ -68,7 +68,7 @@ class RethinkDnsEndpointRepository(private val rethinkDnsEndpointDao: RethinkDns
rethinkDnsEndpointDao.updateEndpoint(name, url, count)
}
- suspend fun getRethinkPlusEndpoint(): RethinkDnsEndpoint {
+ suspend fun getRethinkPlusEndpoint(): RethinkDnsEndpoint? {
return rethinkDnsEndpointDao.getRethinkPlusEndpoint()
}
diff --git a/app/src/main/java/com/celzero/bravedns/net/go/GoProber.java b/app/src/main/java/com/celzero/bravedns/net/go/GoProber.java
index 8f559cc96..9000788dc 100644
--- a/app/src/main/java/com/celzero/bravedns/net/go/GoProber.java
+++ b/app/src/main/java/com/celzero/bravedns/net/go/GoProber.java
@@ -26,9 +26,8 @@
*/
public class GoProber extends Prober {
- private final Context context;
-
private static final String PROBER_TAG = "Prober";
+ private final Context context;
public GoProber(Context context) {
this.context = context;
diff --git a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt
index bb2f7e71e..b560b7dd2 100644
--- a/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt
+++ b/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt
@@ -1315,7 +1315,6 @@ class BraveVPNService :
// if service is up (aka connectionMonitor not null)
// then simply update the existing tunnel
if (connectionMonitor == null) {
- underlyingNetworks = null
connectionMonitor = ConnectionMonitor(this, this)
connectionMonitor?.onVpnStartLocked()
} else {
@@ -1323,6 +1322,10 @@ class BraveVPNService :
}
}
+ if (isNewVpn) {
+ underlyingNetworks = null
+ }
+
val mtu = mtu()
val opts =
appConfig.newTunnelOptions(
@@ -1347,9 +1350,6 @@ class BraveVPNService :
// have app, ip, domain rules. See RefreshDatabase#refresh
rdb.refresh(RefreshDatabase.ACTION_REFRESH_AUTO) {
restartVpn(opts, Networks(null, overlayNetworks), why = "startVpn")
- vpnProtos = Pair(overlayNetworks.has4, overlayNetworks.has6)
- // update the controller, which will update the UI (home screen btm sheet)
- VpnController.updateProtocol(vpnProtos)
// call this *after* a new vpn is created #512
uiCtx("observers") { observeChanges() }
}
@@ -1678,6 +1678,8 @@ class BraveVPNService :
Log.i(LOG_TAG_VPN, "stopped vpn adapter and vpn service")
}
+
+
private fun stopVpnAdapter() {
io("stopVpn") {
if (vpnAdapter == null) {
@@ -1707,8 +1709,6 @@ class BraveVPNService :
nws,
reason
)
- // update the controller, which will update the UI (home screen btm sheet)
- VpnController.updateProtocol(vpnProtos)
}
private suspend fun setPcapMode() {
@@ -1780,6 +1780,7 @@ class BraveVPNService :
}
notifyConnectionStateChangeIfNeeded()
+ informVpnControllerForProtoChange(vpnProtos)
}
private suspend fun logAndToastIfNeeded(msg: String, logLevel: Int = Log.WARN) {
@@ -1799,6 +1800,11 @@ class BraveVPNService :
}
}
+ private fun informVpnControllerForProtoChange(protos: Pair) {
+ // update the controller, which will update the UI (home screen btm sheet)
+ VpnController.updateProtocol(protos)
+ }
+
// protected by vpncontroller.mutex
fun hasTunnel(): Boolean {
return vpnAdapter?.hasTunnel() == true
@@ -2172,6 +2178,8 @@ class BraveVPNService :
persistentState.setVpnEnabled(false)
stopPauseTimer()
+ // reset the underlying networks
+ underlyingNetworks = null
unobserveOrbotStartStatus()
unobserveAppInfos()
diff --git a/app/src/main/java/com/celzero/bravedns/service/IpRulesManager.kt b/app/src/main/java/com/celzero/bravedns/service/IpRulesManager.kt
index e4b8a68b9..3496d2246 100644
--- a/app/src/main/java/com/celzero/bravedns/service/IpRulesManager.kt
+++ b/app/src/main/java/com/celzero/bravedns/service/IpRulesManager.kt
@@ -199,7 +199,7 @@ object IpRulesManager : KoinComponent {
private suspend fun updateRule(uid: Int, ipaddr: String, port: Int, status: IpRuleStatus) {
Log.i(LOG_TAG_FIREWALL, "ip rule, update: $ipaddr for uid: $uid; status: ${status.name}")
// ipaddr is expected to be normalized
- val c = makeCustomIp2(uid, ipaddr, port, status)
+ val c = makeCustomIp(uid, ipaddr, port, status)
db.update(c)
val k = treeKey(ipaddr)
if (!k.isNullOrEmpty()) {
@@ -237,34 +237,36 @@ object IpRulesManager : KoinComponent {
}
getMostSpecificRuleMatch(uid, ipstr, port).let {
- logd("ip rule for $uid $ipstr $port => $it ??")
+ logd("ip rule for $uid $ipstr $port => ${it.name} ??")
if (it != IpRuleStatus.NONE) {
resultsCache.put(ck, it)
return it
}
}
getMostSpecificRuleMatch(uid, ipstr).let {
- logd("ip rule for $uid $ipstr => $it ??")
+ logd("ip rule for $uid $ipstr => ${it.name} ??")
if (it != IpRuleStatus.NONE) {
resultsCache.put(ck, it)
return it
}
}
getMostSpecificRouteMatch(uid, ipstr, port).let {
- logd("route rule for $uid $ipstr $port => $it ??")
+ logd("route rule for $uid $ipstr $port => ${it.name} ??")
if (it != IpRuleStatus.NONE) {
resultsCache.put(ck, it)
return it
}
}
getMostSpecificRouteMatch(uid, ipstr).let {
- logd("route rule for $uid $ipstr => $it ??")
+ logd("route rule for $uid $ipstr => ${it.name} ??")
if (it != IpRuleStatus.NONE) {
resultsCache.put(ck, it)
return it
}
}
- logd("hasRule? NO: $uid, $ipstr, $port")
+
+ logd("hasRule? NO $uid, $ipstr, $port")
+ resultsCache.put(ck, IpRuleStatus.NONE)
return IpRuleStatus.NONE
}
@@ -326,7 +328,7 @@ object IpRulesManager : KoinComponent {
resultsCache.invalidateAll()
}
- private fun makeCustomIp2(
+ private fun makeCustomIp(
uid: Int,
ipAddress: String,
port: Int?,
@@ -342,9 +344,7 @@ object IpRulesManager : KoinComponent {
customIp.wildcard = wildcard
customIp.modifiedDateTime = System.currentTimeMillis()
- val pair = customIp.getCustomIpAddress()
- val ipaddr = pair.first
- val port = pair.second
+ val ipaddr = customIp.getCustomIpAddress().first
// TODO: is this needed in database?
customIp.ruleType =
if (ipaddr.isIPv6) {
@@ -420,7 +420,7 @@ object IpRulesManager : KoinComponent {
"ip rule, add rule for ($uid) ip: $ipstr, $port with status: ${status.name}"
)
val normalizedIp = padAndNormalize(ipstr)
- val c = makeCustomIp2(uid, normalizedIp, port, status)
+ val c = makeCustomIp(uid, normalizedIp, port, status)
db.insert(c)
val k = treeKey(normalizedIp)
if (!k.isNullOrEmpty()) {
@@ -463,7 +463,7 @@ object IpRulesManager : KoinComponent {
db.deleteRule(prevRule.uid, prevRule.ipAddress, prevRule.port)
}
}
- val newRule = makeCustomIp2(prevRule.uid, newIpAddrStr, port, newStatus)
+ val newRule = makeCustomIp(prevRule.uid, newIpAddrStr, port, newStatus)
db.insert(newRule)
val pk = treeKey(prevIpAddrStr)
if (!pk.isNullOrEmpty()) {
@@ -490,7 +490,7 @@ object IpRulesManager : KoinComponent {
var host = ""
var port = ""
- var err: Exception? = null
+ val err: Exception? = null
var j = 0
var k = 0
diff --git a/app/src/main/res/drawable/brave_mode_info.xml b/app/src/main/res/drawable/brave_mode_info.xml
index b4edc48c4..6c11fb4d3 100644
--- a/app/src/main/res/drawable/brave_mode_info.xml
+++ b/app/src/main/res/drawable/brave_mode_info.xml
@@ -3,25 +3,25 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/bs_dns_home_screen.xml b/app/src/main/res/drawable/bs_dns_home_screen.xml
index 95b5300dd..d0187862f 100644
--- a/app/src/main/res/drawable/bs_dns_home_screen.xml
+++ b/app/src/main/res/drawable/bs_dns_home_screen.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/bs_firewall_home_screen.xml b/app/src/main/res/drawable/bs_firewall_home_screen.xml
index 6191599f4..72c8ec87c 100644
--- a/app/src/main/res/drawable/bs_firewall_home_screen.xml
+++ b/app/src/main/res/drawable/bs_firewall_home_screen.xml
@@ -1,10 +1,10 @@
-
+
diff --git a/app/src/main/res/drawable/default_app_icon.xml b/app/src/main/res/drawable/default_app_icon.xml
index 64c4054ec..244b6df64 100644
--- a/app/src/main/res/drawable/default_app_icon.xml
+++ b/app/src/main/res/drawable/default_app_icon.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/dns_home_screen.xml b/app/src/main/res/drawable/dns_home_screen.xml
index 8d18e1d64..c543425f1 100644
--- a/app/src/main/res/drawable/dns_home_screen.xml
+++ b/app/src/main/res/drawable/dns_home_screen.xml
@@ -3,7 +3,7 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/dot_accent.xml b/app/src/main/res/drawable/dot_accent.xml
index ddb9250fe..8abb3a3ee 100644
--- a/app/src/main/res/drawable/dot_accent.xml
+++ b/app/src/main/res/drawable/dot_accent.xml
@@ -1,6 +1,8 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/dot_green.xml b/app/src/main/res/drawable/dot_green.xml
index 5f70fe6b5..c436934e8 100644
--- a/app/src/main/res/drawable/dot_green.xml
+++ b/app/src/main/res/drawable/dot_green.xml
@@ -1,6 +1,8 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/dot_red.xml b/app/src/main/res/drawable/dot_red.xml
index 0bb517b42..3321e4f5b 100644
--- a/app/src/main/res/drawable/dot_red.xml
+++ b/app/src/main/res/drawable/dot_red.xml
@@ -1,6 +1,8 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/dot_yellow.xml b/app/src/main/res/drawable/dot_yellow.xml
index 14bf0c442..a4eba4dbe 100644
--- a/app/src/main/res/drawable/dot_yellow.xml
+++ b/app/src/main/res/drawable/dot_yellow.xml
@@ -1,6 +1,8 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/drawable_purple_gradient.xml b/app/src/main/res/drawable/drawable_purple_gradient.xml
index c0dfd5bba..edcdf6b9e 100644
--- a/app/src/main/res/drawable/drawable_purple_gradient.xml
+++ b/app/src/main/res/drawable/drawable_purple_gradient.xml
@@ -1,10 +1,10 @@
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/fast_scroll_line.xml b/app/src/main/res/drawable/fast_scroll_line.xml
index 84edef8c7..42b1162f2 100644
--- a/app/src/main/res/drawable/fast_scroll_line.xml
+++ b/app/src/main/res/drawable/fast_scroll_line.xml
@@ -1,12 +1,12 @@
+ android:shape="rectangle">
+ android:top="10dp" />
\ No newline at end of file
diff --git a/app/src/main/res/drawable/fast_scroll_line_drawable.xml b/app/src/main/res/drawable/fast_scroll_line_drawable.xml
index 94d56aa79..64190f9fc 100644
--- a/app/src/main/res/drawable/fast_scroll_line_drawable.xml
+++ b/app/src/main/res/drawable/fast_scroll_line_drawable.xml
@@ -1,9 +1,6 @@
-
+
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/fast_scroll_thumb.xml b/app/src/main/res/drawable/fast_scroll_thumb.xml
index 132ec8b6b..84cdad2a7 100644
--- a/app/src/main/res/drawable/fast_scroll_thumb.xml
+++ b/app/src/main/res/drawable/fast_scroll_thumb.xml
@@ -1,17 +1,17 @@
+ android:shape="rectangle">
+ android:topRightRadius="44dp" />
+ android:paddingRight="22dp"
+ android:paddingBottom="22dp" />
diff --git a/app/src/main/res/drawable/fast_scroll_thumb_drawable.xml b/app/src/main/res/drawable/fast_scroll_thumb_drawable.xml
index 761657f89..1bfa13da7 100644
--- a/app/src/main/res/drawable/fast_scroll_thumb_drawable.xml
+++ b/app/src/main/res/drawable/fast_scroll_thumb_drawable.xml
@@ -1,9 +1,6 @@
-
+
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/firewall_home_screen.xml b/app/src/main/res/drawable/firewall_home_screen.xml
index f5ac73b21..cb5d6530a 100644
--- a/app/src/main/res/drawable/firewall_home_screen.xml
+++ b/app/src/main/res/drawable/firewall_home_screen.xml
@@ -3,7 +3,7 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/foss_logo.xml b/app/src/main/res/drawable/foss_logo.xml
index af324d108..db5a78cda 100644
--- a/app/src/main/res/drawable/foss_logo.xml
+++ b/app/src/main/res/drawable/foss_logo.xml
@@ -3,70 +3,70 @@
android:height="61dp"
android:viewportWidth="104"
android:viewportHeight="81">
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_about.xml b/app/src/main/res/drawable/ic_about.xml
index 32d8ae129..dc897ac25 100644
--- a/app/src/main/res/drawable/ic_about.xml
+++ b/app/src/main/res/drawable/ic_about.xml
@@ -3,25 +3,25 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/ic_about_key.xml b/app/src/main/res/drawable/ic_about_key.xml
index f2f696a86..a2a753d18 100644
--- a/app/src/main/res/drawable/ic_about_key.xml
+++ b/app/src/main/res/drawable/ic_about_key.xml
@@ -3,28 +3,28 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/ic_add.xml b/app/src/main/res/drawable/ic_add.xml
index 1adb4fba6..d126c4c89 100644
--- a/app/src/main/res/drawable/ic_add.xml
+++ b/app/src/main/res/drawable/ic_add.xml
@@ -4,18 +4,18 @@
android:alpha="0.75"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_adv_dns_filter.xml b/app/src/main/res/drawable/ic_adv_dns_filter.xml
index 5fd4c6217..cafea0071 100644
--- a/app/src/main/res/drawable/ic_adv_dns_filter.xml
+++ b/app/src/main/res/drawable/ic_adv_dns_filter.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_allow_pass.xml b/app/src/main/res/drawable/ic_allow_pass.xml
index 6f2178c4c..51e893797 100644
--- a/app/src/main/res/drawable/ic_allow_pass.xml
+++ b/app/src/main/res/drawable/ic_allow_pass.xml
@@ -3,34 +3,34 @@
android:height="24dp"
android:viewportWidth="48"
android:viewportHeight="48">
-
-
-
-
-
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_app_info.xml b/app/src/main/res/drawable/ic_app_info.xml
index 8db90dec3..fc7a22db2 100644
--- a/app/src/main/res/drawable/ic_app_info.xml
+++ b/app/src/main/res/drawable/ic_app_info.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="256"
android:viewportHeight="256">
-
+
diff --git a/app/src/main/res/drawable/ic_app_info_accent.xml b/app/src/main/res/drawable/ic_app_info_accent.xml
index 2590d03f6..15e8a7e4c 100644
--- a/app/src/main/res/drawable/ic_app_info_accent.xml
+++ b/app/src/main/res/drawable/ic_app_info_accent.xml
@@ -3,7 +3,7 @@
android:height="18dp"
android:viewportWidth="256"
android:viewportHeight="256">
-
+
diff --git a/app/src/main/res/drawable/ic_arrow_down.xml b/app/src/main/res/drawable/ic_arrow_down.xml
index bab56a1d4..1a22f601f 100644
--- a/app/src/main/res/drawable/ic_arrow_down.xml
+++ b/app/src/main/res/drawable/ic_arrow_down.xml
@@ -3,11 +3,11 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_arrow_down_small.xml b/app/src/main/res/drawable/ic_arrow_down_small.xml
index 592aac91d..d421823b9 100644
--- a/app/src/main/res/drawable/ic_arrow_down_small.xml
+++ b/app/src/main/res/drawable/ic_arrow_down_small.xml
@@ -3,11 +3,11 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_arrow_up.xml b/app/src/main/res/drawable/ic_arrow_up.xml
index 95dde5804..acfeeb0ce 100644
--- a/app/src/main/res/drawable/ic_arrow_up.xml
+++ b/app/src/main/res/drawable/ic_arrow_up.xml
@@ -1,10 +1,10 @@
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ android:strokeLineCap="square" />
diff --git a/app/src/main/res/drawable/ic_authors.xml b/app/src/main/res/drawable/ic_authors.xml
index 39f3c12e7..1df78d3dd 100644
--- a/app/src/main/res/drawable/ic_authors.xml
+++ b/app/src/main/res/drawable/ic_authors.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="256"
android:viewportHeight="256">
-
+
diff --git a/app/src/main/res/drawable/ic_auto_start.xml b/app/src/main/res/drawable/ic_auto_start.xml
index 6e1515ca3..b19626fef 100644
--- a/app/src/main/res/drawable/ic_auto_start.xml
+++ b/app/src/main/res/drawable/ic_auto_start.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="256"
android:viewportHeight="256">
-
+
diff --git a/app/src/main/res/drawable/ic_backup.xml b/app/src/main/res/drawable/ic_backup.xml
index 8e882f9bd..ff66b2da5 100644
--- a/app/src/main/res/drawable/ic_backup.xml
+++ b/app/src/main/res/drawable/ic_backup.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_backup_restore.xml b/app/src/main/res/drawable/ic_backup_restore.xml
index f5a067662..14a82c59f 100644
--- a/app/src/main/res/drawable/ic_backup_restore.xml
+++ b/app/src/main/res/drawable/ic_backup_restore.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_biometric.xml b/app/src/main/res/drawable/ic_biometric.xml
index a11779d21..5800d80c8 100644
--- a/app/src/main/res/drawable/ic_biometric.xml
+++ b/app/src/main/res/drawable/ic_biometric.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_blocklist_update_check.xml b/app/src/main/res/drawable/ic_blocklist_update_check.xml
index 532b567a6..50a1ffe86 100644
--- a/app/src/main/res/drawable/ic_blocklist_update_check.xml
+++ b/app/src/main/res/drawable/ic_blocklist_update_check.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_bypass.xml b/app/src/main/res/drawable/ic_bypass.xml
index 72bed0586..a22f6d5fe 100644
--- a/app/src/main/res/drawable/ic_bypass.xml
+++ b/app/src/main/res/drawable/ic_bypass.xml
@@ -4,32 +4,32 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_bypass_dns_firewall_off.xml b/app/src/main/res/drawable/ic_bypass_dns_firewall_off.xml
index a2d920fd2..7009d6237 100644
--- a/app/src/main/res/drawable/ic_bypass_dns_firewall_off.xml
+++ b/app/src/main/res/drawable/ic_bypass_dns_firewall_off.xml
@@ -4,18 +4,18 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_bypass_dns_firewall_on.xml b/app/src/main/res/drawable/ic_bypass_dns_firewall_on.xml
index 6eef493f6..815322826 100644
--- a/app/src/main/res/drawable/ic_bypass_dns_firewall_on.xml
+++ b/app/src/main/res/drawable/ic_bypass_dns_firewall_on.xml
@@ -3,18 +3,18 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_configure.xml b/app/src/main/res/drawable/ic_configure.xml
index 74963ab1c..f8efa38e3 100644
--- a/app/src/main/res/drawable/ic_configure.xml
+++ b/app/src/main/res/drawable/ic_configure.xml
@@ -3,9 +3,9 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_connectivity_checks.xml b/app/src/main/res/drawable/ic_connectivity_checks.xml
index 6cf868ac7..93aaa83d3 100644
--- a/app/src/main/res/drawable/ic_connectivity_checks.xml
+++ b/app/src/main/res/drawable/ic_connectivity_checks.xml
@@ -3,18 +3,18 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_copy.xml b/app/src/main/res/drawable/ic_copy.xml
index 7a19cbb28..92c769f3f 100644
--- a/app/src/main/res/drawable/ic_copy.xml
+++ b/app/src/main/res/drawable/ic_copy.xml
@@ -3,7 +3,7 @@
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
-
+
diff --git a/app/src/main/res/drawable/ic_cross.xml b/app/src/main/res/drawable/ic_cross.xml
index 89b2948ed..6eb710d48 100644
--- a/app/src/main/res/drawable/ic_cross.xml
+++ b/app/src/main/res/drawable/ic_cross.xml
@@ -1,4 +1,9 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_custom_allow_deny.xml b/app/src/main/res/drawable/ic_custom_allow_deny.xml
index 27165b028..ed2d04b3e 100644
--- a/app/src/main/res/drawable/ic_custom_allow_deny.xml
+++ b/app/src/main/res/drawable/ic_custom_allow_deny.xml
@@ -3,10 +3,10 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml
index f558dc944..cf2ade40e 100644
--- a/app/src/main/res/drawable/ic_delete.xml
+++ b/app/src/main/res/drawable/ic_delete.xml
@@ -3,11 +3,11 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_device_lock.xml b/app/src/main/res/drawable/ic_device_lock.xml
index 5a812c82b..428fada6b 100644
--- a/app/src/main/res/drawable/ic_device_lock.xml
+++ b/app/src/main/res/drawable/ic_device_lock.xml
@@ -1,21 +1,21 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_dns_cache.xml b/app/src/main/res/drawable/ic_dns_cache.xml
index 141174699..8efb16514 100644
--- a/app/src/main/res/drawable/ic_dns_cache.xml
+++ b/app/src/main/res/drawable/ic_dns_cache.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_dns_firewall.xml b/app/src/main/res/drawable/ic_dns_firewall.xml
index 67d91d5f3..04cab6013 100644
--- a/app/src/main/res/drawable/ic_dns_firewall.xml
+++ b/app/src/main/res/drawable/ic_dns_firewall.xml
@@ -3,11 +3,11 @@
android:height="40dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_edit_icon.xml b/app/src/main/res/drawable/ic_edit_icon.xml
index 6f39ce962..bf5d4bbcc 100644
--- a/app/src/main/res/drawable/ic_edit_icon.xml
+++ b/app/src/main/res/drawable/ic_edit_icon.xml
@@ -3,10 +3,10 @@
android:height="48dp"
android:viewportWidth="36"
android:viewportHeight="36">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_edit_icon_grey.xml b/app/src/main/res/drawable/ic_edit_icon_grey.xml
index ed681129e..88bdbd88e 100644
--- a/app/src/main/res/drawable/ic_edit_icon_grey.xml
+++ b/app/src/main/res/drawable/ic_edit_icon_grey.xml
@@ -3,10 +3,10 @@
android:height="24dp"
android:viewportWidth="36"
android:viewportHeight="34">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_fab_uninstall.xml b/app/src/main/res/drawable/ic_fab_uninstall.xml
index 21c0275f8..037b9a30c 100644
--- a/app/src/main/res/drawable/ic_fab_uninstall.xml
+++ b/app/src/main/res/drawable/ic_fab_uninstall.xml
@@ -3,11 +3,11 @@
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_fab_without_border.xml b/app/src/main/res/drawable/ic_fab_without_border.xml
index 049275b79..b397dfcc9 100644
--- a/app/src/main/res/drawable/ic_fab_without_border.xml
+++ b/app/src/main/res/drawable/ic_fab_without_border.xml
@@ -3,11 +3,11 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_fallback.xml b/app/src/main/res/drawable/ic_fallback.xml
index 9ed393cff..c8fd81d89 100644
--- a/app/src/main/res/drawable/ic_fallback.xml
+++ b/app/src/main/res/drawable/ic_fallback.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="16"
android:viewportHeight="16">
-
+
diff --git a/app/src/main/res/drawable/ic_fav_icon.xml b/app/src/main/res/drawable/ic_fav_icon.xml
index 3182e3ce5..518741acb 100644
--- a/app/src/main/res/drawable/ic_fav_icon.xml
+++ b/app/src/main/res/drawable/ic_fav_icon.xml
@@ -3,18 +3,18 @@
android:height="24dp"
android:viewportWidth="22"
android:viewportHeight="22">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_filter.xml b/app/src/main/res/drawable/ic_filter.xml
index 6779c063c..b6eeaba27 100644
--- a/app/src/main/res/drawable/ic_filter.xml
+++ b/app/src/main/res/drawable/ic_filter.xml
@@ -3,11 +3,11 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_filter_error.xml b/app/src/main/res/drawable/ic_filter_error.xml
index 02d05c65a..07560e2bc 100644
--- a/app/src/main/res/drawable/ic_filter_error.xml
+++ b/app/src/main/res/drawable/ic_filter_error.xml
@@ -4,25 +4,25 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/ic_firewall_allow.xml b/app/src/main/res/drawable/ic_firewall_allow.xml
index d50e4c951..2d726d309 100644
--- a/app/src/main/res/drawable/ic_firewall_allow.xml
+++ b/app/src/main/res/drawable/ic_firewall_allow.xml
@@ -3,11 +3,11 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_allow_grey.xml b/app/src/main/res/drawable/ic_firewall_allow_grey.xml
index 5c5c19a42..ba4a40797 100644
--- a/app/src/main/res/drawable/ic_firewall_allow_grey.xml
+++ b/app/src/main/res/drawable/ic_firewall_allow_grey.xml
@@ -4,11 +4,11 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_block.xml b/app/src/main/res/drawable/ic_firewall_block.xml
index 84ea4bb2d..e79b48ca7 100644
--- a/app/src/main/res/drawable/ic_firewall_block.xml
+++ b/app/src/main/res/drawable/ic_firewall_block.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_block_grey.xml b/app/src/main/res/drawable/ic_firewall_block_grey.xml
index aac04694d..1becc64dd 100644
--- a/app/src/main/res/drawable/ic_firewall_block_grey.xml
+++ b/app/src/main/res/drawable/ic_firewall_block_grey.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_bypass_off.xml b/app/src/main/res/drawable/ic_firewall_bypass_off.xml
index 14be5d30e..3a7a9223d 100644
--- a/app/src/main/res/drawable/ic_firewall_bypass_off.xml
+++ b/app/src/main/res/drawable/ic_firewall_bypass_off.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_bypass_on.xml b/app/src/main/res/drawable/ic_firewall_bypass_on.xml
index ec30734ae..bd479e662 100644
--- a/app/src/main/res/drawable/ic_firewall_bypass_on.xml
+++ b/app/src/main/res/drawable/ic_firewall_bypass_on.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_data_off.xml b/app/src/main/res/drawable/ic_firewall_data_off.xml
index 00a118525..a3078a3e2 100644
--- a/app/src/main/res/drawable/ic_firewall_data_off.xml
+++ b/app/src/main/res/drawable/ic_firewall_data_off.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_data_on.xml b/app/src/main/res/drawable/ic_firewall_data_on.xml
index b316d5390..b7f58707a 100644
--- a/app/src/main/res/drawable/ic_firewall_data_on.xml
+++ b/app/src/main/res/drawable/ic_firewall_data_on.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_data_on_grey.xml b/app/src/main/res/drawable/ic_firewall_data_on_grey.xml
index 9d3896324..5b1811658 100644
--- a/app/src/main/res/drawable/ic_firewall_data_on_grey.xml
+++ b/app/src/main/res/drawable/ic_firewall_data_on_grey.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_data_on_grey_alpha.xml b/app/src/main/res/drawable/ic_firewall_data_on_grey_alpha.xml
index 9d3896324..5b1811658 100644
--- a/app/src/main/res/drawable/ic_firewall_data_on_grey_alpha.xml
+++ b/app/src/main/res/drawable/ic_firewall_data_on_grey_alpha.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_exclude_off.xml b/app/src/main/res/drawable/ic_firewall_exclude_off.xml
index 2df2b3671..0d987c2bf 100644
--- a/app/src/main/res/drawable/ic_firewall_exclude_off.xml
+++ b/app/src/main/res/drawable/ic_firewall_exclude_off.xml
@@ -1,10 +1,10 @@
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_exclude_on.xml b/app/src/main/res/drawable/ic_firewall_exclude_on.xml
index a86434d32..e6416c47e 100644
--- a/app/src/main/res/drawable/ic_firewall_exclude_on.xml
+++ b/app/src/main/res/drawable/ic_firewall_exclude_on.xml
@@ -3,7 +3,7 @@
android:height="22dp"
android:viewportWidth="20"
android:viewportHeight="20">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_lockdown_off.xml b/app/src/main/res/drawable/ic_firewall_lockdown_off.xml
index a54409883..80fd7dfdf 100644
--- a/app/src/main/res/drawable/ic_firewall_lockdown_off.xml
+++ b/app/src/main/res/drawable/ic_firewall_lockdown_off.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_lockdown_on.xml b/app/src/main/res/drawable/ic_firewall_lockdown_on.xml
index 63c9614d4..7bcb373bb 100644
--- a/app/src/main/res/drawable/ic_firewall_lockdown_on.xml
+++ b/app/src/main/res/drawable/ic_firewall_lockdown_on.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_firewall_wifi_off.xml b/app/src/main/res/drawable/ic_firewall_wifi_off.xml
index febc1da18..608198814 100644
--- a/app/src/main/res/drawable/ic_firewall_wifi_off.xml
+++ b/app/src/main/res/drawable/ic_firewall_wifi_off.xml
@@ -3,39 +3,39 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
-
-
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_firewall_wifi_on.xml b/app/src/main/res/drawable/ic_firewall_wifi_on.xml
index 0e2907371..3f9821a33 100644
--- a/app/src/main/res/drawable/ic_firewall_wifi_on.xml
+++ b/app/src/main/res/drawable/ic_firewall_wifi_on.xml
@@ -3,32 +3,32 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_firewall_wifi_on_grey.xml b/app/src/main/res/drawable/ic_firewall_wifi_on_grey.xml
index 00fe40670..266344524 100644
--- a/app/src/main/res/drawable/ic_firewall_wifi_on_grey.xml
+++ b/app/src/main/res/drawable/ic_firewall_wifi_on_grey.xml
@@ -4,32 +4,32 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_foreground.xml b/app/src/main/res/drawable/ic_foreground.xml
index 9f7984dcc..1ae094e56 100644
--- a/app/src/main/res/drawable/ic_foreground.xml
+++ b/app/src/main/res/drawable/ic_foreground.xml
@@ -4,14 +4,14 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/ic_github.xml b/app/src/main/res/drawable/ic_github.xml
index 45846d787..7446f42d1 100644
--- a/app/src/main/res/drawable/ic_github.xml
+++ b/app/src/main/res/drawable/ic_github.xml
@@ -3,12 +3,12 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_global_lockdown.xml b/app/src/main/res/drawable/ic_global_lockdown.xml
index ca782e351..5fd7ec9f3 100644
--- a/app/src/main/res/drawable/ic_global_lockdown.xml
+++ b/app/src/main/res/drawable/ic_global_lockdown.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml
index de832bb25..f8bb0b556 100644
--- a/app/src/main/res/drawable/ic_home_black_24dp.xml
+++ b/app/src/main/res/drawable/ic_home_black_24dp.xml
@@ -1,9 +1,9 @@
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:fillColor="#FF000000"
+ android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
diff --git a/app/src/main/res/drawable/ic_http.xml b/app/src/main/res/drawable/ic_http.xml
index 5d7505712..51c7a6564 100644
--- a/app/src/main/res/drawable/ic_http.xml
+++ b/app/src/main/res/drawable/ic_http.xml
@@ -4,16 +4,16 @@
android:alpha="0.5"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_import_conf.xml b/app/src/main/res/drawable/ic_import_conf.xml
index 21cc2e429..5386ec67c 100644
--- a/app/src/main/res/drawable/ic_import_conf.xml
+++ b/app/src/main/res/drawable/ic_import_conf.xml
@@ -4,10 +4,10 @@
android:alpha="0.75"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml
index 52dc60f51..045e8306e 100644
--- a/app/src/main/res/drawable/ic_info.xml
+++ b/app/src/main/res/drawable/ic_info.xml
@@ -3,25 +3,25 @@
android:height="48dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/ic_info_white.xml b/app/src/main/res/drawable/ic_info_white.xml
index cda3d90c9..83726c60e 100644
--- a/app/src/main/res/drawable/ic_info_white.xml
+++ b/app/src/main/res/drawable/ic_info_white.xml
@@ -3,25 +3,25 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/ic_ip_address.xml b/app/src/main/res/drawable/ic_ip_address.xml
index dba3dc7d5..fa36bed78 100644
--- a/app/src/main/res/drawable/ic_ip_address.xml
+++ b/app/src/main/res/drawable/ic_ip_address.xml
@@ -4,30 +4,30 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_ip_network.xml b/app/src/main/res/drawable/ic_ip_network.xml
index ff1bf288f..a6b24a6b9 100644
--- a/app/src/main/res/drawable/ic_ip_network.xml
+++ b/app/src/main/res/drawable/ic_ip_network.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_ipv6.xml b/app/src/main/res/drawable/ic_ipv6.xml
index 5fe2d2360..aa6bb4769 100644
--- a/app/src/main/res/drawable/ic_ipv6.xml
+++ b/app/src/main/res/drawable/ic_ipv6.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_down.xml b/app/src/main/res/drawable/ic_keyboard_arrow_down.xml
index 49d5636ad..a17c2cdda 100644
--- a/app/src/main/res/drawable/ic_keyboard_arrow_down.xml
+++ b/app/src/main/res/drawable/ic_keyboard_arrow_down.xml
@@ -1,9 +1,9 @@
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ android:pathData="M7.41,7.84L12,12.42l4.59,-4.58L18,9.25l-6,6 -6,-6z" />
diff --git a/app/src/main/res/drawable/ic_local_blocklist.xml b/app/src/main/res/drawable/ic_local_blocklist.xml
index 917ff0830..fd9a515fc 100644
--- a/app/src/main/res/drawable/ic_local_blocklist.xml
+++ b/app/src/main/res/drawable/ic_local_blocklist.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_logs.xml b/app/src/main/res/drawable/ic_logs.xml
index c3816803e..69694e87b 100644
--- a/app/src/main/res/drawable/ic_logs.xml
+++ b/app/src/main/res/drawable/ic_logs.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="512"
android:viewportHeight="512">
-
+
diff --git a/app/src/main/res/drawable/ic_logs_accent.xml b/app/src/main/res/drawable/ic_logs_accent.xml
index 8bcd2cb5d..48339fa5f 100644
--- a/app/src/main/res/drawable/ic_logs_accent.xml
+++ b/app/src/main/res/drawable/ic_logs_accent.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="512"
android:viewportHeight="512">
-
+
diff --git a/app/src/main/res/drawable/ic_minus.xml b/app/src/main/res/drawable/ic_minus.xml
index e6001c884..7028a4857 100644
--- a/app/src/main/res/drawable/ic_minus.xml
+++ b/app/src/main/res/drawable/ic_minus.xml
@@ -3,7 +3,7 @@
android:height="48dp"
android:viewportWidth="512"
android:viewportHeight="512">
-
+
diff --git a/app/src/main/res/drawable/ic_network.xml b/app/src/main/res/drawable/ic_network.xml
index de86c761a..34cca0103 100644
--- a/app/src/main/res/drawable/ic_network.xml
+++ b/app/src/main/res/drawable/ic_network.xml
@@ -3,19 +3,19 @@
android:height="24dp"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
-
-
-
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_network_tunnel.xml b/app/src/main/res/drawable/ic_network_tunnel.xml
index 3b819c17c..7d1892214 100644
--- a/app/src/main/res/drawable/ic_network_tunnel.xml
+++ b/app/src/main/res/drawable/ic_network_tunnel.xml
@@ -3,16 +3,16 @@
android:height="16dp"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml
index fa559d44f..4793ffead 100644
--- a/app/src/main/res/drawable/ic_notification.xml
+++ b/app/src/main/res/drawable/ic_notification.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_orbot.xml b/app/src/main/res/drawable/ic_orbot.xml
index 06feba3a8..57558ef58 100644
--- a/app/src/main/res/drawable/ic_orbot.xml
+++ b/app/src/main/res/drawable/ic_orbot.xml
@@ -4,53 +4,53 @@
android:alpha="0.5"
android:viewportWidth="64"
android:viewportHeight="64">
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_other_settings.xml b/app/src/main/res/drawable/ic_other_settings.xml
index ec3eb0da4..79be9eb8b 100644
--- a/app/src/main/res/drawable/ic_other_settings.xml
+++ b/app/src/main/res/drawable/ic_other_settings.xml
@@ -3,10 +3,10 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_pause.xml b/app/src/main/res/drawable/ic_pause.xml
index 63e17675a..57dd4357e 100644
--- a/app/src/main/res/drawable/ic_pause.xml
+++ b/app/src/main/res/drawable/ic_pause.xml
@@ -3,10 +3,10 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_pcap.xml b/app/src/main/res/drawable/ic_pcap.xml
index ee65ab7cd..3defc6e4d 100644
--- a/app/src/main/res/drawable/ic_pcap.xml
+++ b/app/src/main/res/drawable/ic_pcap.xml
@@ -4,39 +4,39 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
-
-
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_plus.xml b/app/src/main/res/drawable/ic_plus.xml
index f138b5538..b83268331 100644
--- a/app/src/main/res/drawable/ic_plus.xml
+++ b/app/src/main/res/drawable/ic_plus.xml
@@ -3,7 +3,7 @@
android:height="48dp"
android:viewportWidth="16"
android:viewportHeight="16">
-
+
diff --git a/app/src/main/res/drawable/ic_prevent_dns_leaks.xml b/app/src/main/res/drawable/ic_prevent_dns_leaks.xml
index e2fb0f718..2002ceec9 100644
--- a/app/src/main/res/drawable/ic_prevent_dns_leaks.xml
+++ b/app/src/main/res/drawable/ic_prevent_dns_leaks.xml
@@ -1,21 +1,21 @@
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_prevent_dns_proxy.xml b/app/src/main/res/drawable/ic_prevent_dns_proxy.xml
index c7ea6e9b3..2d080c05e 100644
--- a/app/src/main/res/drawable/ic_prevent_dns_proxy.xml
+++ b/app/src/main/res/drawable/ic_prevent_dns_proxy.xml
@@ -4,18 +4,18 @@
android:alpha="0.6"
android:viewportWidth="192"
android:viewportHeight="192">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_privacy_policy.xml b/app/src/main/res/drawable/ic_privacy_policy.xml
index e828a3e27..ebb944d06 100644
--- a/app/src/main/res/drawable/ic_privacy_policy.xml
+++ b/app/src/main/res/drawable/ic_privacy_policy.xml
@@ -3,20 +3,20 @@
android:height="24dp"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
-
-
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_proxy.xml b/app/src/main/res/drawable/ic_proxy.xml
index 3287542d3..6671e8f7d 100644
--- a/app/src/main/res/drawable/ic_proxy.xml
+++ b/app/src/main/res/drawable/ic_proxy.xml
@@ -3,7 +3,7 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_proxy_white.xml b/app/src/main/res/drawable/ic_proxy_white.xml
index b73521fd1..6b02762d2 100644
--- a/app/src/main/res/drawable/ic_proxy_white.xml
+++ b/app/src/main/res/drawable/ic_proxy_white.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_qr_code_scanner.xml b/app/src/main/res/drawable/ic_qr_code_scanner.xml
index f36075861..308fcb0eb 100644
--- a/app/src/main/res/drawable/ic_qr_code_scanner.xml
+++ b/app/src/main/res/drawable/ic_qr_code_scanner.xml
@@ -4,7 +4,7 @@
android:alpha="0.75"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_restore.xml b/app/src/main/res/drawable/ic_restore.xml
index b723ae3c0..c59bc55d2 100644
--- a/app/src/main/res/drawable/ic_restore.xml
+++ b/app/src/main/res/drawable/ic_restore.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_right_arrow_chip.xml b/app/src/main/res/drawable/ic_right_arrow_chip.xml
index 448fe7e72..9680937f9 100644
--- a/app/src/main/res/drawable/ic_right_arrow_chip.xml
+++ b/app/src/main/res/drawable/ic_right_arrow_chip.xml
@@ -3,11 +3,11 @@
android:height="18dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_right_arrow_secondary.xml b/app/src/main/res/drawable/ic_right_arrow_secondary.xml
index d881c1f21..10e8f653e 100644
--- a/app/src/main/res/drawable/ic_right_arrow_secondary.xml
+++ b/app/src/main/res/drawable/ic_right_arrow_secondary.xml
@@ -3,11 +3,11 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="22">
-
+
diff --git a/app/src/main/res/drawable/ic_right_arrow_small.xml b/app/src/main/res/drawable/ic_right_arrow_small.xml
index 27bd6d8f0..44aae8f27 100644
--- a/app/src/main/res/drawable/ic_right_arrow_small.xml
+++ b/app/src/main/res/drawable/ic_right_arrow_small.xml
@@ -3,11 +3,11 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_right_arrow_white.xml b/app/src/main/res/drawable/ic_right_arrow_white.xml
index 057e5a02f..02f838175 100644
--- a/app/src/main/res/drawable/ic_right_arrow_white.xml
+++ b/app/src/main/res/drawable/ic_right_arrow_white.xml
@@ -3,11 +3,11 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_save.xml b/app/src/main/res/drawable/ic_save.xml
index b82950175..012985855 100644
--- a/app/src/main/res/drawable/ic_save.xml
+++ b/app/src/main/res/drawable/ic_save.xml
@@ -3,7 +3,7 @@
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1063.2">
-
+
diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml
index c56537844..02639869c 100644
--- a/app/src/main/res/drawable/ic_settings.xml
+++ b/app/src/main/res/drawable/ic_settings.xml
@@ -3,18 +3,18 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_socks5.xml b/app/src/main/res/drawable/ic_socks5.xml
index 5b4b84833..bbb8c20d7 100644
--- a/app/src/main/res/drawable/ic_socks5.xml
+++ b/app/src/main/res/drawable/ic_socks5.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="512"
android:viewportHeight="512">
-
+
diff --git a/app/src/main/res/drawable/ic_statistics.xml b/app/src/main/res/drawable/ic_statistics.xml
index 4142ad67f..044fceb66 100644
--- a/app/src/main/res/drawable/ic_statistics.xml
+++ b/app/src/main/res/drawable/ic_statistics.xml
@@ -3,9 +3,9 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_stop.xml b/app/src/main/res/drawable/ic_stop.xml
index 8ef98c9ad..d0e601ee5 100644
--- a/app/src/main/res/drawable/ic_stop.xml
+++ b/app/src/main/res/drawable/ic_stop.xml
@@ -3,7 +3,7 @@
android:height="80dp"
android:viewportWidth="32"
android:viewportHeight="32">
-
+
diff --git a/app/src/main/res/drawable/ic_telegram.xml b/app/src/main/res/drawable/ic_telegram.xml
index 8a1e17863..ce0ad1927 100644
--- a/app/src/main/res/drawable/ic_telegram.xml
+++ b/app/src/main/res/drawable/ic_telegram.xml
@@ -3,18 +3,18 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_tick.xml b/app/src/main/res/drawable/ic_tick.xml
index 9eccbf250..a5955ffc5 100644
--- a/app/src/main/res/drawable/ic_tick.xml
+++ b/app/src/main/res/drawable/ic_tick.xml
@@ -3,10 +3,10 @@
android:height="16dp"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_tick_normal.xml b/app/src/main/res/drawable/ic_tick_normal.xml
index c2a72ec4e..6e7cd179a 100644
--- a/app/src/main/res/drawable/ic_tick_normal.xml
+++ b/app/src/main/res/drawable/ic_tick_normal.xml
@@ -4,10 +4,10 @@
android:alpha="0.5"
android:viewportWidth="32"
android:viewportHeight="32">
-
-
+
+
diff --git a/app/src/main/res/drawable/ic_translate.xml b/app/src/main/res/drawable/ic_translate.xml
index 8d65718bc..ef2a1a038 100644
--- a/app/src/main/res/drawable/ic_translate.xml
+++ b/app/src/main/res/drawable/ic_translate.xml
@@ -4,11 +4,11 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_udp.xml b/app/src/main/res/drawable/ic_udp.xml
index 8f43c6411..2b1e005f1 100644
--- a/app/src/main/res/drawable/ic_udp.xml
+++ b/app/src/main/res/drawable/ic_udp.xml
@@ -1,37 +1,37 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_unknown_app.xml b/app/src/main/res/drawable/ic_unknown_app.xml
index 1df1588e6..8420bdf56 100644
--- a/app/src/main/res/drawable/ic_unknown_app.xml
+++ b/app/src/main/res/drawable/ic_unknown_app.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_update.xml b/app/src/main/res/drawable/ic_update.xml
index 46a1243a0..aeee0e452 100644
--- a/app/src/main/res/drawable/ic_update.xml
+++ b/app/src/main/res/drawable/ic_update.xml
@@ -4,7 +4,7 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_update_small.xml b/app/src/main/res/drawable/ic_update_small.xml
index a9e040a6a..94596a1e4 100644
--- a/app/src/main/res/drawable/ic_update_small.xml
+++ b/app/src/main/res/drawable/ic_update_small.xml
@@ -3,7 +3,7 @@
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_website.xml b/app/src/main/res/drawable/ic_website.xml
index 01a438746..ee7f22d97 100644
--- a/app/src/main/res/drawable/ic_website.xml
+++ b/app/src/main/res/drawable/ic_website.xml
@@ -7,24 +7,24 @@
android:fillColor="?attr/svgFillColor"
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:strokeWidth="2"
- android:strokeColor="?attr/svgStrokeColor"
android:strokeAlpha="0.5"
+ android:strokeColor="?attr/svgStrokeColor"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
diff --git a/app/src/main/res/drawable/ic_whats_new.xml b/app/src/main/res/drawable/ic_whats_new.xml
index f5d65e5cb..f55cbb6d7 100644
--- a/app/src/main/res/drawable/ic_whats_new.xml
+++ b/app/src/main/res/drawable/ic_whats_new.xml
@@ -3,12 +3,12 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/ic_wireguard_icon.xml b/app/src/main/res/drawable/ic_wireguard_icon.xml
index 42a17c85a..1bb626da6 100644
--- a/app/src/main/res/drawable/ic_wireguard_icon.xml
+++ b/app/src/main/res/drawable/ic_wireguard_icon.xml
@@ -4,67 +4,67 @@
android:alpha="0.5"
android:viewportWidth="192"
android:viewportHeight="192">
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/illustrations_download.xml b/app/src/main/res/drawable/illustrations_download.xml
index 9db544139..fe32a6940 100644
--- a/app/src/main/res/drawable/illustrations_download.xml
+++ b/app/src/main/res/drawable/illustrations_download.xml
@@ -3,61 +3,61 @@
android:height="667.7441dp"
android:viewportWidth="765.59973"
android:viewportHeight="667.7441">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/illustrations_no_record.xml b/app/src/main/res/drawable/illustrations_no_record.xml
index cb9d7656c..8354c74fd 100644
--- a/app/src/main/res/drawable/illustrations_no_record.xml
+++ b/app/src/main/res/drawable/illustrations_no_record.xml
@@ -3,77 +3,77 @@
android:height="400dp"
android:viewportWidth="797.5"
android:viewportHeight="834.5">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/illustrations_welcome_1.xml b/app/src/main/res/drawable/illustrations_welcome_1.xml
index dba8d4803..c5a36031f 100644
--- a/app/src/main/res/drawable/illustrations_welcome_1.xml
+++ b/app/src/main/res/drawable/illustrations_welcome_1.xml
@@ -3,143 +3,143 @@
android:height="714.3182dp"
android:viewportWidth="904.3213"
android:viewportHeight="714.3182">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/illustrations_welcome_2.xml b/app/src/main/res/drawable/illustrations_welcome_2.xml
index 2fafdcc02..775f370ab 100644
--- a/app/src/main/res/drawable/illustrations_welcome_2.xml
+++ b/app/src/main/res/drawable/illustrations_welcome_2.xml
@@ -3,163 +3,163 @@
android:height="831.29517dp"
android:viewportWidth="921.6705"
android:viewportHeight="831.29517">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/new_conf_illustrator.xml b/app/src/main/res/drawable/new_conf_illustrator.xml
index 62c5b4824..96d736fc9 100644
--- a/app/src/main/res/drawable/new_conf_illustrator.xml
+++ b/app/src/main/res/drawable/new_conf_illustrator.xml
@@ -3,32 +3,32 @@
android:height="80dp"
android:viewportWidth="80"
android:viewportHeight="80">
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/osom_logo_stacked.xml b/app/src/main/res/drawable/osom_logo_stacked.xml
index b3f695932..f4a8346fa 100644
--- a/app/src/main/res/drawable/osom_logo_stacked.xml
+++ b/app/src/main/res/drawable/osom_logo_stacked.xml
@@ -3,22 +3,22 @@
android:height="60dp"
android:viewportWidth="2000"
android:viewportHeight="979.8">
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/osom_logos_horizontal.xml b/app/src/main/res/drawable/osom_logos_horizontal.xml
index 0572b5ed3..14cb0f14f 100644
--- a/app/src/main/res/drawable/osom_logos_horizontal.xml
+++ b/app/src/main/res/drawable/osom_logos_horizontal.xml
@@ -3,22 +3,22 @@
android:height="50dp"
android:viewportWidth="2000"
android:viewportHeight="472.5">
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/show_notification.xml b/app/src/main/res/drawable/show_notification.xml
index beadfc8c3..b6c8d4e69 100644
--- a/app/src/main/res/drawable/show_notification.xml
+++ b/app/src/main/res/drawable/show_notification.xml
@@ -4,25 +4,25 @@
android:alpha="0.5"
android:viewportWidth="24"
android:viewportHeight="24">
-
-
-
+
+
+
diff --git a/app/src/main/res/drawable/spinner_both.xml b/app/src/main/res/drawable/spinner_both.xml
index a8fb4ef6d..fc62d2e37 100644
--- a/app/src/main/res/drawable/spinner_both.xml
+++ b/app/src/main/res/drawable/spinner_both.xml
@@ -3,11 +3,11 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
-
+
diff --git a/app/src/main/res/drawable/spinner_outline.xml b/app/src/main/res/drawable/spinner_outline.xml
index 978a7d045..61fd88b56 100644
--- a/app/src/main/res/drawable/spinner_outline.xml
+++ b/app/src/main/res/drawable/spinner_outline.xml
@@ -1,5 +1,7 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/spinner_outline_with_bg.xml b/app/src/main/res/drawable/spinner_outline_with_bg.xml
index 2db15ff80..2910898c3 100644
--- a/app/src/main/res/drawable/spinner_outline_with_bg.xml
+++ b/app/src/main/res/drawable/spinner_outline_with_bg.xml
@@ -1,6 +1,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/text_view_background.xml b/app/src/main/res/drawable/text_view_background.xml
index 3a676d617..b3082cd3c 100644
--- a/app/src/main/res/drawable/text_view_background.xml
+++ b/app/src/main/res/drawable/text_view_background.xml
@@ -9,8 +9,7 @@
- -
+
-
@@ -18,8 +17,7 @@
- -
+
-
@@ -28,8 +26,8 @@
-
+ android:bottom="2dp"
+ android:top="2dp">
diff --git a/app/src/main/res/layout/activity_alerts.xml b/app/src/main/res/layout/activity_alerts.xml
index b2c16ceff..c090e92a1 100644
--- a/app/src/main/res/layout/activity_alerts.xml
+++ b/app/src/main/res/layout/activity_alerts.xml
@@ -1,24 +1,24 @@
+ android:layout_height="match_parent">
+ app:layout_constraintTop_toTopOf="parent" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_app_wise_domain_logs.xml b/app/src/main/res/layout/activity_app_wise_domain_logs.xml
new file mode 100644
index 000000000..83f2b961c
--- /dev/null
+++ b/app/src/main/res/layout/activity_app_wise_domain_logs.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_app_wise_logs.xml b/app/src/main/res/layout/activity_app_wise_ip_logs.xml
similarity index 100%
rename from app/src/main/res/layout/activity_app_wise_logs.xml
rename to app/src/main/res/layout/activity_app_wise_ip_logs.xml
index a1938c749..5368aeaf8 100644
--- a/app/src/main/res/layout/activity_app_wise_logs.xml
+++ b/app/src/main/res/layout/activity_app_wise_ip_logs.xml
@@ -93,8 +93,8 @@
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="20dp"
- android:textAlignment="center"
android:text="@string/ada_ip_no_connection"
+ android:textAlignment="center"
android:textSize="@dimen/heading_font_text_view" />
diff --git a/app/src/main/res/layout/activity_detailed_statistics.xml b/app/src/main/res/layout/activity_detailed_statistics.xml
index 27100dcae..74c0d133d 100644
--- a/app/src/main/res/layout/activity_detailed_statistics.xml
+++ b/app/src/main/res/layout/activity_detailed_statistics.xml
@@ -31,12 +31,12 @@
style="@style/TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:layout_toStartOf="@id/dsa_subtitle"
android:fontFamily="sans-serif-smallcaps"
android:lineSpacingExtra="5dp"
- android:layout_centerVertical="true"
android:padding="10dp"
- android:layout_alignParentStart="true"
- android:layout_toStartOf="@id/dsa_subtitle"
android:text="@string/ssv_app_network_activity_heading"
android:textColor="?attr/primaryLightColorText"
android:textSize="@dimen/extra_large_font_text_view" />
@@ -45,10 +45,10 @@
android:id="@+id/dsa_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
- android:layout_alignParentEnd="true"
android:textColor="?attr/primaryLightColorText"
android:textSize="@dimen/default_font_text_view" />
diff --git a/app/src/main/res/layout/activity_dns_detail.xml b/app/src/main/res/layout/activity_dns_detail.xml
index 3b640faca..1f4bae4d3 100644
--- a/app/src/main/res/layout/activity_dns_detail.xml
+++ b/app/src/main/res/layout/activity_dns_detail.xml
@@ -12,8 +12,8 @@
android:id="@+id/dns_detail_act_tabLayout"
style="@style/TabbedLayoutDefault"
android:layout_width="match_parent"
- android:visibility="gone"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:visibility="gone" />
+ android:layout_height="wrap_content"
+ android:visibility="gone" />
+ android:paddingEnd="5dp">
-
+
+
+ android:layout_margin="8dp"
+ android:layout_marginTop="16dp"
+ android:paddingBottom="5dp"
+ android:text="@string/lbl_configure"
+ android:textColor="?attr/primaryLightColorText"
+ android:textSize="@dimen/extra_large_font_text_view"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
-
+
-
+ android:imeOptions="actionNext"
+ android:inputType="textNoSuggestions|textVisiblePassword" />
+
-
-
+
-
+ android:imeOptions="actionNext"
+ android:inputType="textNoSuggestions|textPassword" />
+
-
-
+
-
+ android:ellipsize="end"
+ android:focusable="false"
+ android:hint="@string/lbl_generated"
+ android:imeOptions="actionNext"
+ android:inputType="none"
+ android:singleLine="true" />
+
-
-
+
-
+ android:imeOptions="actionNext"
+ android:inputType="textNoSuggestions|textVisiblePassword" />
+
-
-
+
-
+ android:hint="@string/lbl_random"
+ android:imeOptions="actionNext"
+ android:inputType="number"
+ android:textAlignment="center" />
+
-
-
+
-
+ app:boxCornerRadiusTopStart="8dp" />
+
-
-
+
-
-
-
-
+ android:hint="@string/lbl_auto"
+ android:imeOptions="actionDone"
+ android:inputType="number"
+ android:textAlignment="center" />
+
-
+
diff --git a/app/src/main/res/layout/bottom_sheet_local_blocklists.xml b/app/src/main/res/layout/bottom_sheet_local_blocklists.xml
index cf984b0b5..8c5812817 100644
--- a/app/src/main/res/layout/bottom_sheet_local_blocklists.xml
+++ b/app/src/main/res/layout/bottom_sheet_local_blocklists.xml
@@ -93,8 +93,8 @@
android:id="@+id/lbbs_download_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
android:layout_margin="10dp"
+ android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/lbbs_configure">
diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml
index 0285af6d4..aa2db1f97 100644
--- a/app/src/main/res/layout/fragment_about.xml
+++ b/app/src/main/res/layout/fragment_about.xml
@@ -1,7 +1,6 @@
@@ -114,11 +114,11 @@
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
+ android:padding="5dp"
android:text="Action"
+ android:textColor="?attr/accentGood"
android:textSize="14sp"
app:iconGravity="textStart"
- android:textColor="?attr/accentGood"
- android:padding="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/icon"
app:layout_constraintTop_toBottomOf="@+id/description_more" />
diff --git a/app/src/main/res/layout/list_item_statistics_summary.xml b/app/src/main/res/layout/list_item_statistics_summary.xml
index 246ef2479..6f3e859d6 100644
--- a/app/src/main/res/layout/list_item_statistics_summary.xml
+++ b/app/src/main/res/layout/list_item_statistics_summary.xml
@@ -12,25 +12,25 @@
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
- android:minHeight="50dp"
+ android:animateLayoutChanges="true"
android:background="?android:attr/selectableItemBackground"
- android:animateLayoutChanges="true">
+ android:minHeight="50dp">
+ android:layout_centerVertical="true"
+ android:alpha="0.9">
@@ -94,9 +94,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
- android:alpha="0.7"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
+ android:alpha="0.7"
android:padding="3dp"
app:trackColor="?attr/background" />
@@ -122,8 +122,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
- android:alpha="0.5"
android:layout_centerVertical="true"
+ android:alpha="0.5"
android:src="@drawable/ic_right_arrow_white" />
@@ -131,6 +131,6 @@
+ android:background="?attr/divider"
+ android:paddingTop="3dp" />
diff --git a/app/src/main/res/layout/list_item_wg_general_interface.xml b/app/src/main/res/layout/list_item_wg_general_interface.xml
index 9f9340dd1..126d5de09 100644
--- a/app/src/main/res/layout/list_item_wg_general_interface.xml
+++ b/app/src/main/res/layout/list_item_wg_general_interface.xml
@@ -49,8 +49,8 @@
android:layout_gravity="center"
android:layout_marginStart="3dp"
android:layout_marginEnd="3dp"
- android:maxLength="15"
android:ellipsize="end"
+ android:maxLength="15"
android:padding="5dp"
android:textAppearance="?attr/textAppearanceHeadline6"
android:textColor="?attr/secondaryTextColor" />
@@ -120,8 +120,8 @@
android:padding="5dp"
android:textColor="?attr/primaryLightColorText"
android:textSize="@dimen/default_font_text_view"
- android:visibility="gone"
- android:textStyle="italic" />
+ android:textStyle="italic"
+ android:visibility="gone" />
+ android:paddingBottom="10dp">
+ android:layout_toEndOf="@id/wg_include_app_list_apk_icon_iv"
+ android:orientation="vertical">
diff --git a/app/src/main/res/layout/list_item_wg_one_interface.xml b/app/src/main/res/layout/list_item_wg_one_interface.xml
index 81b717c86..18ba6d5af 100644
--- a/app/src/main/res/layout/list_item_wg_one_interface.xml
+++ b/app/src/main/res/layout/list_item_wg_one_interface.xml
@@ -49,9 +49,9 @@
android:layout_gravity="center"
android:layout_marginStart="3dp"
android:layout_marginEnd="3dp"
+ android:ellipsize="end"
android:maxLength="15"
android:padding="5dp"
- android:ellipsize="end"
android:textAppearance="?attr/textAppearanceHeadline6"
android:textColor="?attr/secondaryTextColor" />
diff --git a/app/src/main/res/layout/list_item_wg_peers.xml b/app/src/main/res/layout/list_item_wg_peers.xml
index bd9d1550c..3d372ec23 100644
--- a/app/src/main/res/layout/list_item_wg_peers.xml
+++ b/app/src/main/res/layout/list_item_wg_peers.xml
@@ -77,8 +77,8 @@
android:layout_marginTop="8dp"
android:labelFor="@+id/pre_shared_key_text"
android:text="@string/lbl_preshared_key"
- app:layout_constraintStart_toStartOf="parent"
android:visibility="gone"
+ app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/public_key_text" />
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index 036d09bc5..c9ad5f98f 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
-
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index c602b0036..863799bcc 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -42,6 +42,6 @@
-
-
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8089e7a25..1957c3c0f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -97,6 +97,7 @@
Peer
Split
on-device
+ IP
%1$s 🔺
%1$s 🔻
@@ -399,12 +400,15 @@
Chirayu Desai 3.0
1. New feature: Optionally proxy DNS over WireGuard and SOCKS5 proxies.
2. New feature: Optionally enable built-in Android connectivity checks.
- 3. Improved support for editing IP-based firewall rules.
- 4. Improved WireGuard bandwidth.
- 5. Overhauled WireGuard UX.
- 6. Avoid connection leaks for Simple and Always-on WireGuard modes.
- 7. Fix crash when editing WireGuard configurations.
- 8. Fix minor bugs with RDNS+ and other domain-based firewall rules.
+ 3. New feature: List domains and websites an app has connected to.
+ 4. Improved support for editing IP-based firewall rules.
+ 5. Improved WireGuard bandwidth.
+ 6. Overhauled WireGuard UX.
+ 7. Avoid connection leaks for Simple and Always-on WireGuard modes.
+ 8. Fix crash when editing WireGuard configurations.
+ 9. Fix minor bugs with RDNS+ and other domain-based firewall rules.
+ 10. Bug fix: Support multiple rules for a single Trusted IP.
+ 11. Bug fix: Android 14 specific crash.
Help translate this app]]>
diff --git a/app/src/main/res/xml/accessibility_service_config.xml b/app/src/main/res/xml/accessibility_service_config.xml
index e695f2b23..c54f3f4c2 100644
--- a/app/src/main/res/xml/accessibility_service_config.xml
+++ b/app/src/main/res/xml/accessibility_service_config.xml
@@ -1,9 +1,9 @@
\ No newline at end of file
+ android:canRetrieveWindowContent="true"
+ android:description="@string/accessibility_service_description"
+ android:notificationTimeout="1000" />