diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c2af3f9..a695d06 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,41 +3,53 @@
xmlns:tools="http://schemas.android.com/tools">
+
+ android:theme="@style/Theme.Transparent">
+
-
-
-
+
+
+
+
+
+
+
-
\ No newline at end of file
diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/DNSServerDialogFragment.kt b/app/src/main/java/ru/karasevm/privatednstoggle/DNSServerDialogFragment.kt
new file mode 100644
index 0000000..7713217
--- /dev/null
+++ b/app/src/main/java/ru/karasevm/privatednstoggle/DNSServerDialogFragment.kt
@@ -0,0 +1,88 @@
+package ru.karasevm.privatednstoggle
+
+import android.app.Dialog
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.widget.Toast
+import androidx.fragment.app.DialogFragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import ru.karasevm.privatednstoggle.databinding.SheetDnsSelectorBinding
+import ru.karasevm.privatednstoggle.utils.PreferenceHelper.defaultPreference
+import ru.karasevm.privatednstoggle.utils.PreferenceHelper.dns_servers
+import ru.karasevm.privatednstoggle.utils.PrivateDNSUtils
+
+class DNSServerDialogFragment: DialogFragment() {
+
+ private var _binding: SheetDnsSelectorBinding? = null
+ private val binding get() = _binding!!
+
+ private lateinit var linearLayoutManager: LinearLayoutManager
+ private lateinit var adapter: RecyclerAdapter
+ private var items = mutableListOf()
+ private lateinit var sharedPrefs: SharedPreferences
+
+ override fun onCreateDialog(
+ savedInstanceState: Bundle?
+ ): Dialog {
+ return activity?.let {
+ val builder = MaterialAlertDialogBuilder(it)
+ val inflater = requireActivity().layoutInflater
+ _binding = SheetDnsSelectorBinding.inflate(inflater)
+
+ linearLayoutManager = LinearLayoutManager(context)
+ binding.recyclerView.layoutManager = linearLayoutManager
+
+ sharedPrefs = defaultPreference(requireContext())
+ items = sharedPrefs.dns_servers
+ if(items[0] == "") {
+ items.removeAt(0)
+ items.add("dns.google")
+ }
+
+ adapter = RecyclerAdapter(items)
+ binding.recyclerView.adapter = adapter
+
+ builder.setTitle(R.string.select_server)
+ .setView(binding.root)
+ .setPositiveButton(R.string.done
+ ) { _, _ ->
+ dialog?.dismiss()
+ }
+ builder.create()
+ } ?: throw IllegalStateException("Activity cannot be null")
+ }
+
+ override fun onStart() {
+ super.onStart()
+ val dnsMode = PrivateDNSUtils.getPrivateMode(requireActivity().contentResolver)
+ binding.autoSwitch.isChecked = dnsMode.lowercase() == "opportunistic"
+
+ adapter.onItemClick = { position ->
+ binding.autoSwitch.isChecked = false
+ val server = items[position]
+ PrivateDNSUtils.setPrivateMode(requireActivity().contentResolver, PrivateDNSUtils.DNS_MODE_PRIVATE)
+ PrivateDNSUtils.setPrivateProvider(requireActivity().contentResolver, server)
+ Toast.makeText(context, "DNS Server Set", Toast.LENGTH_SHORT).show()
+ }
+
+ binding.autoSwitch.setOnClickListener {
+ if(binding.autoSwitch.isChecked) {
+ PrivateDNSUtils.setPrivateMode(requireActivity().contentResolver, PrivateDNSUtils.DNS_MODE_AUTO)
+ Toast.makeText(context, "DNS Server Set to Auto", Toast.LENGTH_SHORT).show()
+ } else {
+ PrivateDNSUtils.setPrivateMode(requireActivity().contentResolver, PrivateDNSUtils.DNS_MODE_PRIVATE)
+ Toast.makeText(context, "DNS Server Set", Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ activity?.finish()
+ }
+
+ companion object {
+ const val TAG = "DNSServerDialogFragment"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/DnsTileService.kt b/app/src/main/java/ru/karasevm/privatednstoggle/DnsTileService.kt
index 1e19dac..5a33aa9 100644
--- a/app/src/main/java/ru/karasevm/privatednstoggle/DnsTileService.kt
+++ b/app/src/main/java/ru/karasevm/privatednstoggle/DnsTileService.kt
@@ -1,34 +1,23 @@
package ru.karasevm.privatednstoggle
-import android.Manifest
-import android.content.pm.PackageManager
import android.graphics.drawable.Icon
import android.provider.Settings
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
-import android.widget.Toast
import ru.karasevm.privatednstoggle.utils.PreferenceHelper
import ru.karasevm.privatednstoggle.utils.PreferenceHelper.autoMode
import ru.karasevm.privatednstoggle.utils.PreferenceHelper.dns_servers
-
-const val DNS_MODE_OFF = "off"
-const val DNS_MODE_AUTO = "opportunistic"
-const val DNS_MODE_PRIVATE = "hostname"
+import ru.karasevm.privatednstoggle.utils.PrivateDNSUtils
+import ru.karasevm.privatednstoggle.utils.PrivateDNSUtils.DNS_MODE_AUTO
+import ru.karasevm.privatednstoggle.utils.PrivateDNSUtils.DNS_MODE_OFF
+import ru.karasevm.privatednstoggle.utils.PrivateDNSUtils.DNS_MODE_PRIVATE
+import ru.karasevm.privatednstoggle.utils.PrivateDNSUtils.checkForPermission
class DnsTileService : TileService() {
-
- private fun checkForPermission(): Boolean {
- if (checkSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED) {
- return true
- }
- Toast.makeText(this, R.string.permission_missing, Toast.LENGTH_SHORT).show()
- return false
- }
-
override fun onTileAdded() {
super.onTileAdded()
- checkForPermission()
+ checkForPermission(this)
// Update state
qsTile.state = Tile.STATE_INACTIVE
@@ -38,7 +27,7 @@ class DnsTileService : TileService() {
override fun onClick() {
super.onClick()
- if (!checkForPermission()) {
+ if (!checkForPermission(this)) {
return
}
@@ -104,7 +93,7 @@ class DnsTileService : TileService() {
override fun onStartListening() {
super.onStartListening()
- if (!checkForPermission()) {
+ if (!checkForPermission(this)) {
return
}
val dnsMode = Settings.Global.getString(contentResolver, "private_dns_mode")
@@ -137,16 +126,12 @@ class DnsTileService : TileService() {
)
} else if (dnsMode.equals(DNS_MODE_PRIVATE, ignoreCase = true)) {
val dnsProvider = Settings.Global.getString(contentResolver, "private_dns_specifier")
- if (dnsProvider != null) {
- refreshTile(
- qsTile,
- Tile.STATE_ACTIVE,
- dnsProvider,
- R.drawable.ic_private_black_24dp
- )
- } else {
- Toast.makeText(this, R.string.permission_missing, Toast.LENGTH_SHORT).show()
- }
+ refreshTile(
+ qsTile,
+ Tile.STATE_ACTIVE,
+ dnsProvider,
+ R.drawable.ic_private_black_24dp
+ )
}
}
@@ -187,8 +172,8 @@ class DnsTileService : TileService() {
tile.label = label
tile.state = state
tile.icon = Icon.createWithResource(this, icon)
- Settings.Global.putString(contentResolver, "private_dns_mode", dnsMode)
- Settings.Global.putString(contentResolver, "private_dns_specifier", dnsProvider)
+ PrivateDNSUtils.setPrivateMode(contentResolver, dnsMode)
+ PrivateDNSUtils.setPrivateProvider(contentResolver, dnsProvider)
tile.updateTile()
}
diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/SettingsDialogActivity.kt b/app/src/main/java/ru/karasevm/privatednstoggle/SettingsDialogActivity.kt
new file mode 100644
index 0000000..c8a86b6
--- /dev/null
+++ b/app/src/main/java/ru/karasevm/privatednstoggle/SettingsDialogActivity.kt
@@ -0,0 +1,12 @@
+package ru.karasevm.privatednstoggle
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+
+class SettingsDialogActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val newFragment = DNSServerDialogFragment()
+ newFragment.show(supportFragmentManager, DNSServerDialogFragment.TAG)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/utils/PrivateDNSUtils.kt b/app/src/main/java/ru/karasevm/privatednstoggle/utils/PrivateDNSUtils.kt
new file mode 100644
index 0000000..521e53f
--- /dev/null
+++ b/app/src/main/java/ru/karasevm/privatednstoggle/utils/PrivateDNSUtils.kt
@@ -0,0 +1,44 @@
+package ru.karasevm.privatednstoggle.utils
+
+import android.Manifest
+import android.content.ContentResolver
+import android.content.Context
+import android.content.pm.PackageManager
+import android.provider.Settings
+import android.widget.Toast
+import androidx.core.content.ContextCompat.checkSelfPermission
+import ru.karasevm.privatednstoggle.R
+
+object PrivateDNSUtils {
+ const val DNS_MODE_OFF = "off"
+ const val DNS_MODE_AUTO = "opportunistic"
+ const val DNS_MODE_PRIVATE = "hostname"
+
+ private const val PRIVATE_DNS_MODE = "private_dns_mode"
+ private const val PRIVATE_DNS_PROVIDER = "private_dns_specifier"
+
+ fun getPrivateMode(contentResolver: ContentResolver): String {
+ return Settings.Global.getString(contentResolver, PRIVATE_DNS_MODE)
+ }
+
+ fun getPrivateProvider(contentResolver: ContentResolver): String {
+ return Settings.Global.getString(contentResolver, PRIVATE_DNS_PROVIDER)
+ }
+
+ fun setPrivateMode(contentResolver: ContentResolver, value: String) {
+ Settings.Global.putString(contentResolver, PRIVATE_DNS_MODE, value)
+ }
+
+ fun setPrivateProvider(contentResolver: ContentResolver, value: String?) {
+ Settings.Global.putString(contentResolver, PRIVATE_DNS_PROVIDER, value)
+ }
+
+ fun checkForPermission(context: Context): Boolean {
+ if (checkSelfPermission(context, Manifest.permission.WRITE_SECURE_SETTINGS) == PackageManager.PERMISSION_GRANTED) {
+ return true
+ }
+ Toast.makeText(context, R.string.permission_missing, Toast.LENGTH_SHORT).show()
+ return false
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/sheet_dns_selector.xml b/app/src/main/res/layout/sheet_dns_selector.xml
new file mode 100644
index 0000000..6cf14cb
--- /dev/null
+++ b/app/src/main/res/layout/sheet_dns_selector.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2f37be2..c148b93 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -9,7 +9,9 @@
Add
Privacy Policy
Enable auto
+ Select Server
Automatic (opportunistic) DNS mode will now be available in the tile
+ Done
Cancel
Delete
Are you sure you want to delete server?
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 7cf8d95..2f2bf2c 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -10,4 +10,17 @@
- true
- @android:color/transparent
+
+
\ No newline at end of file