diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/service/DnsTileService.kt b/app/src/main/java/ru/karasevm/privatednstoggle/service/DnsTileService.kt index f1b25ae..1bb1944 100644 --- a/app/src/main/java/ru/karasevm/privatednstoggle/service/DnsTileService.kt +++ b/app/src/main/java/ru/karasevm/privatednstoggle/service/DnsTileService.kt @@ -8,6 +8,7 @@ import android.graphics.drawable.Icon import android.provider.Settings import android.service.quicksettings.Tile import android.service.quicksettings.TileService +import android.util.Log import androidx.core.content.ContextCompat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -35,6 +36,8 @@ class DnsTileService : TileService() { private val repository: DnsServerRepository by lazy { (application as PrivateDNSApp).repository } private val job = SupervisorJob() private val scope = CoroutineScope(Dispatchers.IO + job) + private val sharedPreferences by lazy { PreferenceHelper.defaultPreference(this) } + private var isBroadcastReceiverRegistered = false override fun onTileAdded() { super.onTileAdded() @@ -53,9 +56,8 @@ class DnsTileService : TileService() { val dnsMode = Settings.Global.getString(contentResolver, "private_dns_mode") val dnsProvider = Settings.Global.getString(contentResolver, "private_dns_specifier") - val sharedPrefs = PreferenceHelper.defaultPreference(this) if (dnsMode.equals(DNS_MODE_OFF, ignoreCase = true)) { - if (sharedPrefs.autoMode == AUTO_MODE_OPTION_AUTO || sharedPrefs.autoMode == AUTO_MODE_OPTION_OFF_AUTO) { + if (sharedPreferences.autoMode == AUTO_MODE_OPTION_AUTO || sharedPreferences.autoMode == AUTO_MODE_OPTION_OFF_AUTO) { changeDNSServer(DNS_MODE_AUTO, dnsProvider) } else { changeDNSServer(DNS_MODE_PRIVATE, dnsProvider) @@ -66,10 +68,10 @@ class DnsTileService : TileService() { } else if (dnsMode.equals(DNS_MODE_PRIVATE, ignoreCase = true)) { scope.launch { if (getNextAddress(dnsProvider) == null) { - if (sharedPrefs.autoMode == AUTO_MODE_OPTION_PRIVATE) { + if (sharedPreferences.autoMode == AUTO_MODE_OPTION_PRIVATE) { changeDNSServer(DNS_MODE_PRIVATE, null) } else { - if (sharedPrefs.autoMode == AUTO_MODE_OPTION_AUTO) { + if (sharedPreferences.autoMode == AUTO_MODE_OPTION_AUTO) { changeDNSServer(DNS_MODE_AUTO, dnsProvider) } else { changeDNSServer(DNS_MODE_OFF, dnsProvider) @@ -134,10 +136,9 @@ class DnsTileService : TileService() { if (!checkForPermission(this)) { return } - val sharedPrefs = PreferenceHelper.defaultPreference(this) // Require unlock to change mode according to user preference - val requireUnlock = sharedPrefs.requireUnlock + val requireUnlock = sharedPreferences.requireUnlock if (isLocked && requireUnlock) { unlockAndRun(this::cycleState) } else { @@ -151,12 +152,13 @@ class DnsTileService : TileService() { * Refreshes the state of the tile */ private fun refreshTile() { + val isPermissionGranted = checkForPermission(this) val dnsMode = Settings.Global.getString(contentResolver, "private_dns_mode") when (dnsMode?.lowercase()) { DNS_MODE_OFF -> { setTile( qsTile, - Tile.STATE_INACTIVE, + if (!isPermissionGranted) Tile.STATE_UNAVAILABLE else Tile.STATE_INACTIVE, getString(R.string.dns_off), R.drawable.ic_off_black_24dp ) @@ -165,7 +167,7 @@ class DnsTileService : TileService() { DNS_MODE_AUTO -> { setTile( qsTile, - Tile.STATE_INACTIVE, + if (!isPermissionGranted) Tile.STATE_UNAVAILABLE else Tile.STATE_INACTIVE, getString(R.string.dns_auto), R.drawable.ic_auto_black_24dp ) @@ -178,7 +180,7 @@ class DnsTileService : TileService() { val dnsServer = repository.getFirstByServer(activeAddress) setTile( qsTile, - Tile.STATE_ACTIVE, + if (!isPermissionGranted) Tile.STATE_UNAVAILABLE else Tile.STATE_ACTIVE, // display server address if either there is no label or the server is not known dnsServer?.label?.ifBlank { activeAddress } ?: activeAddress, R.drawable.ic_private_black_24dp @@ -189,7 +191,7 @@ class DnsTileService : TileService() { else -> { setTile( qsTile, - Tile.STATE_INACTIVE, + if (!isPermissionGranted) Tile.STATE_UNAVAILABLE else Tile.STATE_INACTIVE, getString(R.string.dns_unknown), R.drawable.ic_unknown_black_24dp ) @@ -205,12 +207,10 @@ class DnsTileService : TileService() { override fun onStartListening() { super.onStartListening() - if (!checkForPermission(this)) { - return - } // Prevent some crashes if (qsTile == null) { + Log.w(TAG, "onStartListening: qsTile is null") return } @@ -222,14 +222,17 @@ class DnsTileService : TileService() { IntentFilter("refresh_tile"), ContextCompat.RECEIVER_NOT_EXPORTED ) - + isBroadcastReceiverRegistered = true refreshTile() - } override fun onStopListening() { super.onStopListening() - unregisterReceiver(broadcastReceiver) + if (isBroadcastReceiverRegistered) { + unregisterReceiver(broadcastReceiver) + isBroadcastReceiverRegistered = false + } + } override fun onDestroy() { @@ -292,4 +295,8 @@ class DnsTileService : TileService() { repository.getNextByServer(currentAddress) } } -} \ No newline at end of file + + companion object { + private const val TAG = "DnsTileService" + } +} diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/ui/DNSServerDialogFragment.kt b/app/src/main/java/ru/karasevm/privatednstoggle/ui/DNSServerDialogFragment.kt index 5b8bf0f..b2fa284 100644 --- a/app/src/main/java/ru/karasevm/privatednstoggle/ui/DNSServerDialogFragment.kt +++ b/app/src/main/java/ru/karasevm/privatednstoggle/ui/DNSServerDialogFragment.kt @@ -17,6 +17,7 @@ import ru.karasevm.privatednstoggle.data.DnsServerViewModelFactory import ru.karasevm.privatednstoggle.databinding.SheetDnsSelectorBinding import ru.karasevm.privatednstoggle.model.DnsServer import ru.karasevm.privatednstoggle.util.PrivateDNSUtils +import ru.karasevm.privatednstoggle.util.PrivateDNSUtils.checkForPermission class DNSServerDialogFragment : DialogFragment() { @@ -68,7 +69,12 @@ class DNSServerDialogFragment : DialogFragment() { override fun onStart() { super.onStart() - + if (!checkForPermission(requireContext())) { + Toast.makeText( + context, R.string.permission_missing, Toast.LENGTH_SHORT + ).show() + dialog!!.dismiss() + } adapter.onItemClick = { id -> when (id) { OFF_ID -> { diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/ui/OptionsDialogFragment.kt b/app/src/main/java/ru/karasevm/privatednstoggle/ui/OptionsDialogFragment.kt index 094d1ba..2ca7b14 100644 --- a/app/src/main/java/ru/karasevm/privatednstoggle/ui/OptionsDialogFragment.kt +++ b/app/src/main/java/ru/karasevm/privatednstoggle/ui/OptionsDialogFragment.kt @@ -14,6 +14,7 @@ import ru.karasevm.privatednstoggle.util.PrivateDNSUtils class OptionsDialogFragment : DialogFragment() { private var _binding: DialogOptionsBinding? = null private val binding get() = _binding!! + private val sharedPreferences by lazy { PreferenceHelper.defaultPreference(requireContext()) } override fun onCreateDialog( savedInstanceState: Bundle? @@ -34,8 +35,7 @@ class OptionsDialogFragment : DialogFragment() { override fun onStart() { super.onStart() - val sharedPrefs = PreferenceHelper.defaultPreference(requireContext()) - val autoModeOption = sharedPrefs.autoMode + val autoModeOption = sharedPreferences.autoMode when (autoModeOption) { PrivateDNSUtils.AUTO_MODE_OPTION_OFF -> binding.autoOptionRadioGroup.check(R.id.autoOptionOff) PrivateDNSUtils.AUTO_MODE_OPTION_AUTO -> binding.autoOptionRadioGroup.check(R.id.autoOptionAuto) @@ -44,20 +44,20 @@ class OptionsDialogFragment : DialogFragment() { } binding.autoOptionRadioGroup.setOnCheckedChangeListener { _, checkedId -> when (checkedId) { - R.id.autoOptionOff -> sharedPrefs.autoMode = PrivateDNSUtils.AUTO_MODE_OPTION_OFF - R.id.autoOptionAuto -> sharedPrefs.autoMode = PrivateDNSUtils.AUTO_MODE_OPTION_AUTO - R.id.autoOptionOffAuto -> sharedPrefs.autoMode = + R.id.autoOptionOff -> sharedPreferences.autoMode = PrivateDNSUtils.AUTO_MODE_OPTION_OFF + R.id.autoOptionAuto -> sharedPreferences.autoMode = PrivateDNSUtils.AUTO_MODE_OPTION_AUTO + R.id.autoOptionOffAuto -> sharedPreferences.autoMode = PrivateDNSUtils.AUTO_MODE_OPTION_OFF_AUTO - R.id.autoOptionPrivate -> sharedPrefs.autoMode = + R.id.autoOptionPrivate -> sharedPreferences.autoMode = PrivateDNSUtils.AUTO_MODE_OPTION_PRIVATE } } - val requireUnlock = sharedPrefs.requireUnlock + val requireUnlock = sharedPreferences.requireUnlock binding.requireUnlockSwitch.isChecked = requireUnlock binding.requireUnlockSwitch.setOnCheckedChangeListener { _, isChecked -> - sharedPrefs.requireUnlock = isChecked + sharedPreferences.requireUnlock = isChecked } } } \ No newline at end of file diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/util/BackupUtils.kt b/app/src/main/java/ru/karasevm/privatednstoggle/util/BackupUtils.kt index 549dd9c..304f1db 100644 --- a/app/src/main/java/ru/karasevm/privatednstoggle/util/BackupUtils.kt +++ b/app/src/main/java/ru/karasevm/privatednstoggle/util/BackupUtils.kt @@ -74,6 +74,6 @@ object BackupUtils { } } sharedPreferences.autoMode = legacyBackup.autoMode?: 0 - sharedPreferences.requireUnlock = legacyBackup.requireUnlock?: false + sharedPreferences.requireUnlock = legacyBackup.requireUnlock == true } } \ No newline at end of file diff --git a/app/src/main/java/ru/karasevm/privatednstoggle/util/PrivateDNSUtils.kt b/app/src/main/java/ru/karasevm/privatednstoggle/util/PrivateDNSUtils.kt index 73a1bc9..9441421 100644 --- a/app/src/main/java/ru/karasevm/privatednstoggle/util/PrivateDNSUtils.kt +++ b/app/src/main/java/ru/karasevm/privatednstoggle/util/PrivateDNSUtils.kt @@ -5,9 +5,7 @@ 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 @Suppress("unused") object PrivateDNSUtils { @@ -45,15 +43,10 @@ object PrivateDNSUtils { } 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 + return checkSelfPermission( + context, + Manifest.permission.WRITE_SECURE_SETTINGS + ) == PackageManager.PERMISSION_GRANTED } } \ No newline at end of file